为什么 Symfony 5.1 不能识别“routes.php”文件中配置的路由?

Cac*_*nde 3 php symfony symfony-routing symfony5

我在尝试使用config/routes.phpSymfony 5.1 中的文件配置我的路由时遇到了困难。

根据Symfony 路由文档,我应该能够在 PHP 文件中配置我的路由:

您可以在单独的 YAML、XML 或PHP文件中定义它们,而不是在控制器类中定义路由。主要优点是它们不需要任何额外的依赖。

但实际上,Symfony 仅在我将路由放入文件时才识别路由routes.yaml

在文件routes.php 中配置的路由会导致错误“找不到用于“GET /something”的路由(404 Not Found)”。运行时debug:router,不会列出这些路由。

routes.yaml.

在另一个使用 的项目中Symfony 5.0.8,路由配置 viaroutes.php就像一个魅力。

这是我测试它的方式:

  1. 创建了一个控制器(省略,因为它不相关,任何控制器都可以)

  2. 创建了一个routes.php文件:

//config/routes.php example

use App\Controller;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return function(RoutingConfigurator $routes)
{
    $routes->add('schools_list', '/schools')
        ->controller([Controller\SchoolController::class, 'list'])
        ->methods(['GET']);
};
Run Code Online (Sandbox Code Playgroud)
  1. 运行debug:router将导致:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
 ---------------- -------- -------- ------ -------------------------- 
Run Code Online (Sandbox Code Playgroud)
  1. 在里面配置相同的路由routes.yaml
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
 ---------------- -------- -------- ------ -------------------------- 
Run Code Online (Sandbox Code Playgroud)
  1. 运行debug:router将导致:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
  schools_list     GET      ANY      ANY    /schools                  
 ---------------- -------- -------- ------ -------------------------- 
Run Code Online (Sandbox Code Playgroud)

yiv*_*ivi 8

在 Symfony < 5.1 上,默认Kernel::configureRoutes()看起来像这样

protected function configureRoutes(RouteCollectionBuilder $routes): void
{
    $confDir = $this->getProjectDir().'/config';

    $routes->import($confDir.'/{routes}/'.$this->environment.'/*'.self::CONFIG_EXTS, '/', 'glob');
    $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob');
    $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
Run Code Online (Sandbox Code Playgroud)

特别注意Kernel::CONFIG_EXTS,它被设置为

private const CONFIG_EXTS = '.{php,xml,yaml,yml}';
Run Code Online (Sandbox Code Playgroud)

所以它会尝试从 PHP、XML 或 YAML 文件加载路由(它甚至会尝试从带有.yml扩展名的文件加载 YAML )。

但在 Symfony 5.1+ 上,此方法已更改为

protected function configureRoutes(RoutingConfigurator $routes): void
{
    $routes->import('../config/{routes}/'.$this->environment.'/*.yaml');
    $routes->import('../config/{routes}/*.yaml');
    $routes->import('../config/{routes}.yaml');
}
Run Code Online (Sandbox Code Playgroud)

现在它只尝试默认加载 YAML 文件。是的,伤心。但它有一个非常简单的修复方法。

(另请注意,RouteCollectionBuilder已被替换为RoutingConfigurator,因为类型提示前者已在 5.1 中弃用)。

只需更改您Kernel::configureRoutes()的 PHP 文件帐户即可:

protected function configureRoutes(RoutingConfigurator $routes): void
{
    $extensions = '{php,yaml}';

    $routes->import('../config/{routes}/' . $this->environment . "/*.$extensions");
    $routes->import("../config/{routes}/*.$extensions");
    $routes->import("../config/{routes}.$extensions");
}
Run Code Online (Sandbox Code Playgroud)

您将准备好出发。

  • 嗯,这是一个意想不到的变化。他们对服务文件也做了同样的事情。我找不到任何有关他们为何进行此更改的文档。 (2认同)