At the core of the Symfony CMF Routing component sits the
is used as a replacement for Symfony's default routing system.
ChainRouter works by accepting a set of prioritized routing
implementations, commonly referred to as "routers".
When handling an incoming request, the
ChainRouter iterates over the
configured routers, sorted by their configured priority, until one of them is
the request or to
the URL and provide the request parameters.
Historically, the router had to do the matching on the URL string alone.
Since Symfony 2.2, it can alternatively implement the
RequestMatcherInterface to do the matching on the full
Request object if it wants to
use other request information into account like the domain or
ChainRouter supports both types of route
Adding Routers to the Chain¶
Routers are added using the
add method of the
ChainRouter. Use this to
add the default Symfony router:
1 2 3 4 5 6
use Symfony\Component\Routing\Router; use Symfony\Cmf\Component\Routing\ChainRouter; $chainRouter = new ChainRouter(); $chainRouter->add(new Router(...)); $chainRouter->match('/foo/bar');
Now, when the
ChainRouter matches a request, it will ask the Symfony
Router to see if the request matches. If there is no match, it will throw a
If you add a new router, for instance the
DynamicRouter, it will be
called after the Symfony Router (because that was added first). To control the
order, you can use the second argument of the
add method to set a priority.
Higher priorities are sorted first.
1 2 3 4 5 6 7 8
use Symfony\Cmf\Component\Routing\DynamicRouter; // ... $chainRouter->add(new Router(...), 1); $dynamicRouter = new DynamicRouter(...); // ... $chainRouter->add($dynamicRouter, 100);
You'll learn how to instantiate the DynamicRouter later in this article.
Register Routers Compiler Pass¶
This component provides a
RegisterRoutersPass. If you use the
Symfony Dependency Injection Component, you can use this compiler pass to
register all routers with a specific tag:
1 2 3 4 5 6 7 8
use Symfony\Cmf\Component\Routing\DependencyInjection\Compiler\RegisterRoutersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; // a ContainerBuilder $container = ...; $pass = new RegisterRoutersPass('cmf_routing.router', 'router'); $container->addCompilerPass($pass);
After adding the passes and configuring the container builder, you continue with compiling the container as explained in the Symfony DI Component compilation section.
You can optionally configure the chain router service name. The compiler pass
will modify this service definition to register the routers when the chain
router is loaded from the container. If you do not specify anything, the
service name is
You can also configure the tag name you want to use with the second argument to
the compiler pass constructor. If you don't, the default tag is
you are using the Symfony CMF RoutingBundle,
this tag is already active with the default name.
ChainRouter is incapable of, by itself, making any actual routing
decisions. Its sole responsibility is managing the given set of Routers,
which are responsible for matching a request and determining its parameters.
You can easily create your own routers by implementing
RouterInterface but the Symfony CMF
Routing Component already includes a powerful route matching system that you
can extend to your needs.
Symfony Default Router¶
The Symfony routing mechanism is itself a
which means you can use it as a Router in the
ChainRouter. This allows you
to use the default routing declaration system. Read more about this router in
the Routing Component article of the core documentation.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.