Is it possible to retrieve info about a certain route by its name, or get a list of all routes?
I need to be able to fetch the _controller
value in defaults
for any route, not only the current.
Is this possible and how?
P.S.: I found I could get the path to the routes YAML being used, but reparsing it seems unnecessary and heavy.
I am really good at answering my own questions..
To get routes use getRouteCollection()
on the router ($this -> get('router') -> getRouteCollection()
inside a controller), then you get RouteCollection instance on which you can all()
or get($name)
.
As described in my comment above Router::getRouteCollection
is really slow and not intended for use in production code.
So if you really need it fast, you have to hack your way through it. Be warned, this is going to be hackish:
Directly accessing the dumped route data
To speed up route matching, Symfony compiles all static routes into one big PHP class file. This file is generated by Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper
and declares a Symfony\Component\Routing\Generator\UrlGenerator
that stores all route definitions in a private static called $declaredRoutes
.
$declaredRoutes
is an array of compiled route fields indexed by the route's name. Among others (see below) these fields also contain the route defaults.
In order to access $declaredRoutes
we have to use a \ReflectionProperty.
So the actual code is:
// If you don't use a custom Router (e.g., a chained router) you normally
// get the Symfony router from the container using:
// $symfonyRouter = $container->get('router');
// After that, you need to get the UrlGenerator from it.
$generator = $symfonyRouter->getGenerator();
// Now read the dumped routes.
$reflectionProperty = new \ReflectionProperty($generator, 'declaredRoutes');
$reflectionProperty->setAccessible(true);
$dumpedRoutes = $reflectionProperty->getValue($generator);
// The defaults are at index #1 of the route array (see below).
$routeDefaults = $dumpedRoutes['my_route'][1];
Fields of the route array
The fields of each route are filled by the above mentioned Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper
like this:
// [...]
$compiledRoute = $route->compile();
$properties = array();
$properties[] = $compiledRoute->getVariables();
$properties[] = $route->getDefaults();
$properties[] = $route->getRequirements();
$properties[] = $compiledRoute->getTokens();
$properties[] = $compiledRoute->getHostTokens();
$properties[] = $route->getSchemes();
// [...]
So to access its requirements you would use:
$routeRequirements = $dumpedRoutes['my_route'][2];
Bottom line
I've looked through the Symfony manual, the source code, forums, stackoverflow etc. but still wasn't able to find a better way of doing this.
It's brutal, ignores the API, and might break in future updates (although it hasn't changed in the most recent Symfony 4.1: PhpGeneratorDumper on GitHub).
But it's rather short and fast enough to be used in production.