create filter in controller symfony2
Sometimes you need to make changes to the Response object, after it is returned by your controller,
but before it is rendered as output to the client (e.g. the browser). You may want to set some extra
response headers, or "completely mess up the content" of the response. You can accomplish this by
creating an event listener that listens to the
Put the event listener in, for example /src/Acme/DemoBundle/EventListener/ResponseListener.php:
Now define the ResponseListener as a service in
Notice the “tag” tag, by which the kernel recognizes this service as an event listener. The event attribute tells the kernel which event this listener listens to. The “method” attribute tells which method should be called when the
In case you don’t want any other events to tamper with the Response, add a call to
kernel.response
event. I give you a sample event listener which changes the Content-Type
header in case the requested format is json and the browser’s accepted response format contains "text/html" in that case, at least in my experience,
the browser doesn’t render the JSON string as plain text when the status code is 4xx or 5xx. So in
these situations, the event listener changes the “Content-Type” to “text/plain”, to be sure you always
get decent output in the browser.
Put the event listener in, for example /src/Acme/DemoBundle/EventListener/ResponseListener.php:
namespace Acme\DemoBundle\EventListener;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class ResponseListener
{
public function onKernelResponse(FilterResponseEvent $event)
{
$request = $event->getRequest();
// only do something when the requested format is "json"
if ($request->getRequestFormat() != 'json') {
return;
}
// only do something when the client accepts "text/html" as response format
if (false === strpos($request->headers->get('Accept'), 'text/html')) {
return;
}
// set the "Content-Type" header of the response
$event->getResponse()->headers->set('Content-Type', 'text/plain');
}
}
Now define the ResponseListener 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.filter_response_listener" class="Acme\DemoBundle\EventListener\ResponseListener">
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
</service>
</services>
</container>
Notice the “tag” tag, by which the kernel recognizes this service as an event listener. The event attribute tells the kernel which event this listener listens to. The “method” attribute tells which method should be called when the
kernel.response
event occurs.
In case you don’t want any other events to tamper with the Response, add a call to
$event->stopPropagation().
Good stuff! Thanks for sharing this.
ReplyDeleteSymfony's events are really powerful but I've yet to find a case where I needed to hook into the response event. Have you and what was your use case?