Scaling Silex applications (part II). Using RouteCollection

In the post Scaling Silex applications I wanted to organize a one Silex application. In one comment Igor Wiedler recommended us to use RouteCollections instead of define the routes with a Symfony’s Dependency Injection Container. Because of that I started to hack a little bit about it and here I show you my outcomes:

I want to build an imaginary application with silex. This application has also one Api and one little blog. I want to organize those parts. Our index.php file

// www/index.php
require_once __DIR__ . '/../vendor/autoload.php';

use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\RouteCollection;
use Silex\Application;

$app = new Application();

$app['routes'] = $app->extend('routes', function (RouteCollection $routes, Application $app) {
    $loader     = new YamlFileLoader(new FileLocator(__DIR__ . '/../config'));
    $collection = $loader->load('routes.yml');

    return $routes;


Now our routes.yml file:

# config/routes.yml

  path: /
  defaults: { _controller: 'Gonzalo123\AppController::homeAction' }

  path: /hello/{name}
  defaults: { _controller: 'Gonzalo123\AppController::helloAction' }

  prefix: /api
  resource: api.yml

  prefix: /blog
  resource: blog.yml

As we can see we have separated the main routing file into different files: api.yml (for the Api) and blog.yml (for the blog)

# config/api.yml

  path:     /list
  defaults: { _controller: 'Gonzalo123\ApiController::listAction' }
# blog.yml

  path:     /
  defaults: { _controller: 'Gonzalo123\BlogController::homeAction' }

And now we can create our controllers:

// lib/Gonzalo123/AppController.php

namespace Gonzalo123;

use Symfony\Component\HttpFoundation\Response;
use Silex\Application;

class AppController
    public function homeAction()
        return new Response("AppController::homeAction");

    public function helloAction(Application $app, $name)
        return new Response("Hello" . $app->escape($name));
// lib/Gonzalo123/ApiController.php

namespace Gonzalo123;

use Symfony\Component\HttpFoundation\Response;

class ApiController
    public function listAction()
        return new Response("AppController::listAction");
// lib/Gonzalo123/BlogController.php

namespace Gonzalo123;

use Symfony\Component\HttpFoundation\Response;

class BlogController
    public function homeAction()
        return new Response("BlogController::homeAction");

And that’s all. Here also the needed dependencies within our composer.json file


source code at github.

About Gonzalo Ayuso

Web Architect. PHP, Python, Node, Angular, ionic, PostgreSQL, Linux, ... Always learning.

Posted on March 4, 2013, in php, silex, Symfony, Technology and tagged , , . Bookmark the permalink. 27 Comments.

  1. whether it enables the system to create a bundle using Silex

  2. i try to add weprofierProvider like this :
    // web profiler service
    $app->register($profiler = new \Silex\Provider\WebProfilerServiceProvider(), array(
    ‘profiler.cache_dir’ => __DIR__.’/../cache’,
    $app->mount(‘/_profiler’, $profiler);

    but this make an error:
    Twig_Error_Syntax: The function “path” does not exist in “@WebProfiler/Profiler/toolbar_js.html.twig” at line 15

    • I don’t understand your problem. It looks that it’s out of the scope of this post. To use the WebProfilerServiceProvider you need to follow the instructions that appear within the WebProfilerServiceProvider documentation. It works without problems.

  3. Good solution. Thanks.
    But how can i set and use custom vars (ex. layouts) for any routes/collections in yaml file?
    And what about middlewares?

  4. Good Job.

    I’m new in Silex. (Since Bilbostack speach of Eguiluz 🙂 Old school PHP programmer, with very bad habits, trying to re-learn. And bad english :$

    One question. ¿how can you access $app and $request from homeAction() ? Don’t want to do with global, neither passing in all the methods… :$

    (no se si se me entiende… 😀 )

    • Gonzalo Ayuso

      be careful. If you use globals you will burn in hell :). It’spretty straightforward. You can use Request through Dependency injection and if you need $app you need to use use keyword:


      use Symfony\Component\HttpFoundation\Request;


      $app->get('/', function($Request $request) use ($app){

      (y sí. Sí que se te entiende 🙂 )

  5. Hi, good job!
    I have a question: If I want to use a before hook with this, its possible?

    • AFAIK you cannot use middlewares when using route collection. In the previous post we discus about it in the comments, but when we are using route collection we cannot define middlewares (before and after) in the yaml file (of course if we hack a little bit). I think the best solution is to use the event dispatcher.

  6. How to inject Silex\Application for every action in a Controller..?

    • You don’t need to inject it. RouteCollection does it. As you can see in the examples, you can use parameters in public functions and Silex call them with with the properly request parameter. But also you can inject the whole SilexApplication. You only need to define the type of the input parameter with the properly type (Silex\Application). This is called “Hollywood principle”

  7. Hi! First of all, good job and thanks for share your knowlodge with us! I guess there is a little mistake in your code. In ApiController.php you put the code ‘return new Response(“AppController::listAction”);’. I guess you should write ‘return new Response(“ApiController::listAction”);’. Am I wrong?


  8. I Using version 1.2 Silex

    “require”: {
    “silex/silex”: “~1.2”,


    Not working others routers,Only this router…

    path: /
    defaults: { _controller: ‘Gonzalo123\AppController::homeAction’ }

    Where is the wrong?

  9. Hi Gonzalo,

    Sorry, I know this post is a little bit old, but … do you know if it’s common (or possible) in Silex/Symfony set a route where I can receive from the url the name of the action to be called (ex: /foo/{action}/)? I have a lot of actions in my app and a I think it will be more
    lighter than set all controller::action routes individually.

    • I’m not sure. The first thing come to my mind is create a proxy action and in this action parse uri and redirect to action depending on the request.

  10. Im trying your example. But get an error when trying the following:

    use Path\To\MyApplication;

    $application = new MyApplication();

    $application[‘routes’] = $application->extend(‘routes’,function (RouteCollection $routes,Application $application){

    Argument 2 passed to {closure}() must be an instance of Application

    I have a external MyApplication.php that´s holds the following:

    namespace Path\To;

    use Silex\Application;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Config\FileLocator;
    use symfony\Component\Routing\Loader\YamlFileLoader;
    use symfony\Component\Routing\RouteCollection;
    use Silex\Provider;

    class MyApplication extends \Silex\Application

    public function myLoader(){



    Is my Pimple to old. I´m using psr-4 and I can see in the Pimple lib composer.json file that it´s using psr-0

  1. Pingback: Новости » Blog Archive » Дайджест интересных новостей и материалов из мира PHP за последние две недели №12 (25.02.2013 — 11.03.2013)

  2. Pingback: Новости » Blog Archive » Дайджест интересных новостей и материалов из мира PHP за последние две недели №12 (25.02.2013 — 11.03.2013)

  3. Pingback: Working with AngularJS and Silex as Resource provider | Gonzalo Ayuso | Web Architect

  4. Pingback: Bundles in Silex using Stack | Gonzalo Ayuso | Web Architect

  5. Pingback: Дайджест интересных новостей и материалов из мира PHP за последние две недели №12 (25.02.2013 — 11.03.2013) - Juds

Leave a Reply to rfontanelli Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: