Resolving Controllers With Symfony And A DI Container

For a project I am working on at the moment, we are using Symfony’s great routing component. The other day, I had to set up the routes to work together with our controllers and stumbled upon something that I would like to document here.

By adding a _controller parameter, such as ‘PostsController::show‘, to a route, Symfony’s ControllerResolver can automatically resolve the controller class given a request object. The ControllerResolver is a part of the HttpKernel component, and also contains an interface, so you can implement it however you like. In my particular case, I actually needed to resolve the class from my DI container, and only needed the resolver to resolve the arguments of the method. I was not going to implement my own ControllerResolver, so here is what I did instead:

// First, fetch the controller string from the request
// Could be something like 'PostsController::show'
$controllerString = $app->request->attributes->get('_controller');

// Next, split the controller string and pass it to two variables
list($class, $method) = explode('::', $controllerString);

// Resolve the controller class out of the DI container
$controller = $app->get($class);

// And use the ControllerResolver to get the arguments
// of the method
$resolver = new ControllerResolver();
$arguments = $resolver->getArguments(
    $app->request,
    [$class, $method]
);

// Now that we have the class and the arguments, we
// can finally call the controller and have it return a response
$response = call_user_func_array(
    [$controller, $method],
    $arguments
);

Leave a Reply

Your email address will not be published. Required fields are marked *