Symfony2: Obtaining the Request Object

In this quick post I am looking at how to obtain the Request object in a Symfony2 controller as a service. This is actually covered in the docs but in one of the earlier introductory pieces and so is easily missed or forgotten about by the time you actually need to know it. I know I missed this and have previously not shown the correct way to do this.

If you are extending the base controller then its getRequest() method will retrieve the Request object from the container. If you are making your controllers services then you will generally inject in the services, you would have requested from the container, to the constructor or via a setter method. This is not the correct way to work with the Request object as it has a narrower scope than the controller. This basically means that the controller can be used for multiple requests whereas a Request object should only be used for the single request it represents. This means that a fresh request object should be injected each time an action of the controller is called rather than just when the controller is created.

The base controller uses its injected container to get a new Request object each time the action is called, so one way would be to inject the controller itself into the service. There are many reasons not do this which I have covered elsewhere. Fortunately there is a simple way to avoid having to do this, thanks to a cool feature of the framework; Symfony2 will automatically inject the Request object into your actions each time they are called, if you ask for it in the following way:

use Symfony\Component\HttpFoundation\Request;

//--

public function someAction(Request $request)
{
    // ...
}

The key here is the type hint of Symfony\Component\HttpFoundation\Request, as long as this is in place the Request object will be injected in as a method argument. This avoids any scope issues without having to inject the container. This will work for controllers whether they are services or not and regardless of whether there are any other method arguments. So, for example, you can still combine this with annotated parameter conversion:

use Symfony\Component\HttpFoundation\Request;
use ExampleBunlde\Entities\BlogPost;

//--

 /**
  * @ParamConverter
  */
public function someAction(BlogPost $blogPost, Request $request)
{
    // ...
}