Important note: the solution provided here is not right. Please read my other post on this, in which I reveal the right solution for this problem.

Symfony 1 had the lovely routing.load_configuration event. Listening to this event enabled the developer to add some routes dynamically, "on-the-fly". Plugins used to do this most of the time. I was looking for a way to accomplish the same in Symfony 2. I've used the following as a solution.

We are going to listen to the kernel.request event, but we make sure we get notified in an early stage, so that the router hasn't done it's magic yet. Then we quickly add some extra routes to the RouteCollection.

Create a routing listener

First we need an event listener, let's call it RoutingListener. The router will be injected by defining this dependency in the service's definition (see below). onEarlyKernelRequest will be the method that responds to the kernel.request event and adds an extra route to the router's route collection:

// in src/Acme/DemoBundle/EventListener/RoutingListener.php

namespace Acme\DemoBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;

use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Routing\Route;

class RoutingListener
{
    protected $router;

    public function __construct(RouterInterface $router)
    {
        $this->router = $router;
    }

    public function onEarlyKernelRequest(GetResponseEvent $event)
    {
        // create a new route; other arguments would be an 
        // array containing requirements and an array with options
        $route = new Route('/welcome-to-symfony2', array(
            '_controller' => 'AcmeDemoBundle:Welcome:index',
        ));

        $this->router->getRouteCollection()->add('extraRoute', $route);
    }
}

Now we should announce the existence of this listener to the kernel itself. We can do this by defining the listener as a service in /src/Acme/DemoBundle/Resources/services.xml:

<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <!-- ... --->

        <service id="acme.routing_listener" class="Acme\DemoBundle\EventListener\RoutingListener">
            <argument type="service" id="router" />
            <tag name="kernel.event_listener" event="kernel.request" method="onEarlyKernelRequest" priority="255" />
        </service>

    </services>
</container>

I wonder which value is really appropriate for "priority", but at least this one works.

As you can see, we register the service using the tag "kernel.event_listener" as a service which responds to the kernel event kernel.request. Upon this event, the onEarlyKernelRequest should be fired and this adds the extra route. The service has one dependency, namely the router, which will be injected as the first argument of the constructor.

Test the setup by browsing to /app_dev.php/welcome-to-symfony2. You should now see the welcome page of your Symfony2 installation.

Nice, but...

Your newly added routes won't appear in the output of the console command router:debug, since the kernel.request only gets fired for web applications. Nevertheless, the WebProfilerExtraBundle shows all the routes correctly. (You might even ask if a router:debug command actually is an appropriate console command, since routing is a typical "web" thing, but I admit it may be a little annoying that these "on-the-fly" created routes don't appear in the list.)

PHP Symfony2 configuration events request routing
Comments
This website uses MailComments: you can send your comments to this post by email. Read more about MailComments, including suggestions for writing your comments (in HTML or Markdown).
Al Jey

you're the man, man!!!!
I just love this, best solution ever.
I've been looking for something this elegant for a few months already)))

andrew

Hi Matthias,
I’m getting a “No route found” error same as Maria . my sf version is 2.0.8.
Your articles are so awesome,thanks your hard work.

Matthias Noback

Hi Andrew, as I wrote to Maria, see http://php-and-symfony.matt... for how you should try to accomplish this (in a much better way than described above).

Maria Lansole

Hi Matthias.

Nice post. I've tried to do what you said, but I'm getting a "No route found" error.
I've tried to debug the route collection and everything looks ok - The route is there. Any idea?

Note: When debugging the route collection I've noticed that all routes have the _controller like: "Bundle\FooBundle\Controller\FooController::fooAction". And, the route created as you're saying above appear like "BundleFooBundle:Foo:foo" - strange?

Cheers,
Maria

Matthias Noback

Okay, so I have completely redone this and the result is a new post, see http://php-and-symfony.matt... Good luck!

Matthias Noback

Thanks! I have not found any problem with this yet, though it is strange that both alternatives work (using the short or the long notation for controllers). Possibly this has something to do with different versions of Symfony2. I will try that later. Bye!