The Symfony2 default Router was developed to handle static Route definitions,
as they are usually declared in configuration files, prior to execution.
The complete routing configuration is injected in the constructor. It then
SymfonyComponentRoutingMatcherUrlMatcher with this
configuration, rather than having the matcher injected as a service. This makes
the default router a poor choice to handle dynamically defined routes. To
handle large numbers of user created routes, this component contains the
DynamicRouter that is configured with a
The actual matching logic depends on the underlying matcher implementation you
choose. You can easily use you own matching strategy by passing it to the
DynamicRouter constructor. As part of this component, the
NestedMatcher is already provided.
The DynamicRouter further allows to modify the resulting parameters of the
routing match, using a set of
RouteEnhancerInterface that can be easily
DynamicRouter is also able to generate URLs from
ProviderBasedGenerator can generate URLs loaded from a
RouteProviderInterface instance. The
Route to generate the URL from any content object that
RouteReferrersInterface, meaning you can generate a URL
directly from a content object.
Optionally, you can provide an Event Dispatcher to the dynamic router. If you do, it will trigger one of the following two events during the match process, depending on which method is used:
- cmf_routing.pre_dynamic_match (Dispatched at the beginning of the
- cmf_routing.pre_dynamic_match_request (Dispatched at the beginning of the
matchRequestmethod. In the context of the Symfony2 full stack framework, only this event will be triggered.)
Symfony\Cmf\Component\Routing\Event\Events class contains the event
constants. To learn how to register the events, see
"How to create an Event Listener" in the core documentation.
Optionally, and following the matching process, a set of
RouteEnhancerInterface instances can be applied by the
Route enhancers are a way to manipulate the parameters from the matched route
before the framework continues. They can be used, for example, to dynamically
assign a controller or to keep logic out of the controller by determining
parameters or "upcasting" request parameters to to the objects they correspond
The component already provides some general purpose enhancers. They all follow the principle to never change an existing field but only add fields if they do not exist yet:
RouteContentEnhancer: If the route is instanceof
RouteObjectInterface, this enhancer sets the target field to the return value of
FieldMapEnhancer: Configured with a key-value map. If a specified field of the match contains a key, the target field is set to the value.
FieldByClassEnhancer: Configured with a map of class names to values. If the specified field contains an object that is an instance of a class in the map, sets the target field to the corresponding value. Note that the first match is taken, should the objects be instance of more than one of the classes. This enhancer is for example used to determine the controller and template based on the class of a Content document. This enhancer is similar to
FieldMapEnhancer, but doing an
instanceofcheck rather than string comparison for the map keys.
FieldPresenceEnhancer: If a field is present in the route match, sets an other field to a specified value if that field is not set yet.
You can also create your own route enhancer by creating a class which
Route enhancers are registered using the
addRouteEnhancer method, which has
an optional second argument to provide the priority.
Route Enhancer Compiler Pass¶
This component provides a
RegisterRouteEnhancersPass. If you use the
Symfony2 Dependency Injection Component, you can use this compiler pass to
register all enhancers having a specific tag with the dynamic router:
1 2 3 4 5 6 7 8
use Symfony\Cmf\Component\Routing\DependencyInjection\Compiler\RegisterRouterEnhancersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; // a ContainerBuilder $container = ...; $pass = new RegisterRouterEnhancersPass('cmf_routing.dynamic_router', 'dynamic_router_route_enhancer'); $container->addCompilerPass($pass);
After adding the passes and configuring the container builder, you continue with compiling the container as explained in the Symfony2 DI Component compilation section.
You can optionally configure the dynamic router service name. The compiler pass
will modify this service definition to register the enhancers when the dynamic
router is loaded from the container. If you do not specify anything, the
default 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
dynamic_router_route_enhancer. If you are using the
Symfony2 CMF RoutingBundle, this tag is
already active with the default name.
You can build redirections by implementing the
It can redirect to an absolute URI, a route name that can be generated by any
Router in the chain or to another
Notice that the actual redirection logic is not handled by the bundle. You should implement your own logic to handle the redirection. For an example of implementing that redirection under the full Symfony2 stack, refer to the RoutingBundle.
Apart from matching an incoming request to a set of parameters, a Router
is also responsible for generating an URL from a route and its parameters.
ChainRouter iterates over its known routers until one of them is
able to generate a matching URL.
UrlMatcherInterface to match a
Request/URL to its corresponding parameters, the
DynamicRouter also uses
UrlGeneratorInterface instance, which allows it to generate an URL from
The generator method looks like this:
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH);
In Symfony2 core, the
$name has to be a string with the configured name
of the route to generate. The CMF routing component adds generators that handle
alternative semantics of
ProviderBasedGenerator extends Symfony2's default
UrlGenerator (which, in turn,
and - if the name is not already a
Route object - loads the Route from the
Route provider. It then lets the core logic generate the URL from that
The CMF component also includes the
ContentAwareGenerator, which extends
ProviderBasedGenerator, that checks if
$name is an object
RouteReferrersReadInterface. If it is, it gets the
from that object. Using the
ContentAwareGenerator, you can generate URLs
for your content in three ways:
- Either pass a
Routeobject as $name
- Or pass a
RouteReferrersInterfaceobject that is your content as $name
- Or provide an implementation of
ContentRepositoryInterfaceand pass the id of the content object as parameter
If you want to implement your own generator for
$name``s that are not
strings, you need to implement the ``ChainedRouterInterface and implement the
supports($name) method to tell the
ChainRouter if your router can
$name to generate a URL.
In order to let the DynamicRouter know if it can try to generate a route with an
object, generators that are able to do so have to implement the
VersatileGeneratorInterface and return true for the
call with any object they can handle.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.