5

I'm having a hard time trying to configure my routes using a config/routes.php file in Symfony 5.1.

As per the Symfony routing documentation, I should be able to configure my routes in a PHP file:

Instead of defining routes in the controller classes, you can define them in a separate YAML, XML or PHP file. The main advantage is that they don't require any extra dependency.

But in practice, Symfony only recognizes the routes if I put my routes in a file routes.yaml.

Routes configured inside a file routes.php result in the error "No route found for "GET /something" (404 Not Found)". When running debug:router, these routes are not listed.

The same route works great when configured in routes.yaml.

In a different project using Symfony 5.0.8, route configuration via routes.php is working like a charm.

This is how I tested it:

  1. Created a controller (omitted, since it's no relevant, any controller would do)

  2. Created a routes.php file:

//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. Running debug:router will result in:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
 ---------------- -------- -------- ------ -------------------------- 
  1. Configured the same route inside routes.yaml:
#config/routes.yaml
schools_list:
    path: /schools
    controller: App\Controller\SchoolController::list
    methods: GET
  1. Running debug:router will result in:
 ---------------- -------- -------- ------ -------------------------- 
  Name             Method   Scheme   Host   Path                      
 ---------------- -------- -------- ------ -------------------------- 
  _preview_error   ANY      ANY      ANY    /_error/{code}.{_format}  
  schools_list     GET      ANY      ANY    /schools                  
 ---------------- -------- -------- ------ -------------------------- 
yivi
  • 42,438
  • 18
  • 116
  • 138
Caconde
  • 4,177
  • 7
  • 35
  • 32

1 Answers1

14

On Symfony < 5.1, the default Kernel::configureRoutes() looked like 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');
}

Notice specifically Kernel::CONFIG_EXTS, which is set to:

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

So it will try loading routes from PHP, XML OR YAML files (it will even attempt to load YAML from files with the .yml extension).

But on Symfony 5.1+, this method 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');
}

Now it only attempts to load YAML files by default. Yup, sad. But it has a very easy fix.

(Notice also that RouteCollectionBuilder has been replaced with RoutingConfigurator, since type-hinting the former has been deprecated on 5.1).

Just change your Kernel::configureRoutes() to account for your PHP files:

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");
}

And you will be ready to go.

yivi
  • 42,438
  • 18
  • 116
  • 138
  • 2
    Well that was an unexpected change. They did the same for service files as well. I could not find any documentation on why they made this change. – Cerad Jun 03 '20 at 12:38
  • I think I remember a blog post that mentioned it at some point, but I can't find it now @Cerad. True, it's not mentioned in the docs anywhere I could find. – yivi Jun 03 '20 at 13:16
  • 1
    Thanks for your help, @yivi! As @Cerad said, this change is not in the docs. I found this [commit](https://github.com/symfony/recipes/commit/5d24d659fc54e2ed564ae93f2f09a2fefe0c850f) that makes the change you mentioned in the answer, and this [other one](https://github.com/symfony/recipes/commit/8da7d03c93669667772d4cd9f1f7cd4cd3f9513b) that allows `.php` files again, but it was merged and, then, reverted. – Caconde Jun 03 '20 at 13:23
  • There was some discussion about this on the Symfony slack channel. The only explanation seems to be that it is slightly faster to build the cache by not having to look for multiple file extensions. Seems kind of shaky to me but oh well. I suspect there will be more changes coming. – Cerad Jun 04 '20 at 14:08
  • Having this same problem in 5.2 but the accepted solution doesn't work. – Sherri Jan 12 '21 at 14:54