Почему Symfony 5.1 не распознает маршруты, настроенные в файле route.php?

Мне трудно настроить маршруты с помощью файла config/routes.php в Symfony 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, конфигурация маршрута через routes.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']);
};
  1. Запуск debug:router приведет к:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
 ---------------- -------- -------- ------ -------------------------- 
  1. Настроил тот же маршрут внутри routes.yaml:
#config/routes.yaml
schools_list:
    path: /schools
    controller: App\Controller\SchoolController::list
    methods: GET
  1. Запуск debug:router приведет к:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
  schools_list     GET      ANY      ANY    /schools                  
 ---------------- -------- -------- ------ -------------------------- 

person Caconde    schedule 02.06.2020    source источник


Ответы (1)


В Symfony ‹ 5.1 Kernel::configureRoutes() по умолчанию выглядело так: noreferrer">это:

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, который установлен в:

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

Таким образом, он попытается загрузить маршруты из файлов PHP, XML ИЛИ YAML (он даже попытается загрузить YAML из файлов с расширением .yml).

Но в 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');
}

Теперь он только пытается загрузить файлы 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");
}

И вы будете готовы к работе.

person yivi    schedule 03.06.2020
comment
Что ж, это было неожиданное изменение. То же самое они сделали и для служебных файлов. Я не смог найти никакой документации о том, почему они внесли это изменение. - person Cerad; 03.06.2020
comment
Я думаю, что помню сообщение в блоге, в котором упоминалось об этом, но я не могу найти его сейчас @Cerad. Правда, нигде в документах, которые я смог найти, об этом не упоминается. - person yivi; 03.06.2020
comment
Спасибо за помощь, @yivi! Как сказал @Cerad, этого изменения нет в документах. Я нашел этот commit, который вносит изменение, которое вы упомянули в ответе, и это другой, который снова разрешает .php файлов, но он был объединен, а затем восстановлен. - person Caconde; 03.06.2020
comment
Об этом было обсуждение на слабом канале Symfony. Единственное объяснение, по-видимому, заключается в том, что создание кеша немного быстрее, поскольку не нужно искать несколько расширений файлов. Мне кажется немного шатким, ну да ладно. Подозреваю, что изменений будет больше. - person Cerad; 04.06.2020
comment
Такая же проблема в 5.2, но принятое решение не работает. - person Sherri; 12.01.2021