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

Posted

技术标签:

【中文标题】为啥 Symfony 5.1 不能识别“routes.php”文件中配置的路由?【英文标题】:Why doesn't Symfony 5.1 recognize routes configured on a "routes.php" file?为什么 Symfony 5.1 不能识别“routes.php”文件中配置的路由? 【发布时间】:2020-09-21 10:25:22 【问题描述】:

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

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

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

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

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

routes.yaml 中配置时,相同的路由效果很好。

在另一个使用Symfony 5.0.8 的项目中,通过routes.php 进行的路由配置非常有效。

这是我测试它的方式:

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

    创建了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']);
;
    运行 debug:router 将导致:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/code._format  
 ---------------- -------- -------- ------ -------------------------- 
    routes.yaml内部配置了相同的路由:
#config/routes.yaml
schools_list:
    path: /schools
    controller: App\Controller\SchoolController::list
    methods: GET
    运行 debug:router 将导致:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/code._format  
  schools_list     GET      ANY      ANY    /schools                  
 ---------------- -------- -------- ------ -------------------------- 

【问题讨论】:

【参考方案1】:

在 Symfony Kernel::configureRoutes() 看起来像 this:

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');

特别注意Kernel::CONFIG_EXTS,其中is set to:

private const CONFIG_EXTS = '.php,xml,yaml,yml';

因此它会尝试从 PHP、XML 或 YAML 文件加载路由(它甚至会尝试从扩展名为 .yml 的文件加载 YAML)。

但是在 Symfony 5.1+ 上,这个方法 has been changed to:

protected function configureRoutes(RoutingConfigurator $routes): void

    $routes->import('../config/routes/'.$this->environment.'/*.yaml');
    $routes->import('../config/routes/*.yaml');
    $routes->import('../config/routes.yaml');

现在它默认只尝试加载 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");

然后你就可以出发了。

【讨论】:

嗯,这是一个意想不到的变化。他们对服务文件也做了同样的事情。我找不到任何关于他们为何做出此更改的文档。 我想我记得有一篇博文提到过它,但我现在找不到它@Cerad。没错,在我能找到的任何地方的文档中都没有提到它。 感谢您的帮助,@yivi!正如@Cerad 所说,此更改不在文档中。我发现这个commit 做出了你在答案中提到的更改,而这个other one 再次允许.php 文件,但它被合并了,然后又恢复了。 在 Symfony slack 频道上对此进行了一些讨论。唯一的解释似乎是通过不必查找多个文件扩展名来构建缓存稍微快一些。对我来说似乎有点不稳定,但哦,好吧。我怀疑会有更多的变化。 在 5.2 中遇到同样的问题,但接受的解决方案不起作用。

以上是关于为啥 Symfony 5.1 不能识别“routes.php”文件中配置的路由?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在 Laravel 5.7 中捕获我定义的 Route 请求的文件 URI?

Symfony 5.1 弃用 RouteCollectionBuilder -> RoutingConfigurator

无法在 Symfony 5.1 中安装 orm-pack

Symfony\Component\Routing\Exception\RouteNotFoundException: Route [Lala.search] 未定义

Symfony2 Route 仅在整数时获取参数

symfony 不能在 Windows Server 2008 上运行