Symfony Framework Events

Symfony Framework Events

When the Symfony Framework (or anything using the HttpKernel) handles a request, a few core events are dispatched so that you can add listeners throughout the process. These are called the "kernel events". For a larger explanation, see The HttpKernel Component.

Kernel Events

Each event dispatched by the kernel is a subclass of KernelEvent. This means that each event has access to the following information:

getRequestType()
Returns the type of the request (HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST).
getKernel()
Returns the Kernel handling the request.
getRequest()
Returns the current Request being handled.

kernel.request

Event Class: GetResponseEvent

This event is dispatched very early in Symfony, before the controller is determined.

Read more on the kernel.request event.

These are the built-in Symfony listeners registered to this event:

Listener Class Name Priority
ProfilerListener 1024
TestSessionListener 192
SessionListener 128
RouterListener 32
LocaleListener 16
Firewall 8

kernel.controller

Event Class: FilterControllerEvent

This event can be an entry point used to modify the controller that should be executed:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

public function onKernelController(FilterControllerEvent $event)
{
    $controller = $event->getController();
    // ...

    // the controller can be changed to any PHP callable
    $event->setController($controller);
}
Read more on the kernel.controller event.

This is the built-in Symfony listener related to this event:

Listener Class Name Priority
RequestDataCollector 0

kernel.view

Event Class: GetResponseForControllerResultEvent

This event is not used by the FrameworkBundle, but it can be used to implement a view sub-system. This event is called only if the Controller does not return a Response object. The purpose of the event is to allow some other return value to be converted into a Response.

The value returned by the Controller is accessible via the getControllerResult() method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpFoundation\Response;

public function onKernelView(GetResponseForControllerResultEvent $event)
{
    $val = $event->getControllerResult();
    $response = new Response();

    // ... somehow customize the Response from the return value

    $event->setResponse($response);
}
Read more on the kernel.view event.

kernel.response

Event Class: FilterResponseEvent

The purpose of this event is to allow other systems to modify or replace the Response object after its creation:

1
2
3
4
5
6
public function onKernelResponse(FilterResponseEvent $event)
{
    $response = $event->getResponse();

    // ... modify the response object
}

The FrameworkBundle registers several listeners:

ProfilerListener
Collects data for the current request.
WebDebugToolbarListener
Injects the Web Debug Toolbar.
ResponseListener
Fixes the Response Content-Type based on the request format.
EsiListener
Adds a Surrogate-Control HTTP header when the Response needs to be parsed for ESI tags.
Read more on the kernel.response event.

These are the built-in Symfony listeners registered to this event:

Listener Class Name Priority
EsiListener 0
ResponseListener 0
ResponseListener 0
ProfilerListener -100
TestSessionListener -128
WebDebugToolbarListener -128
StreamedResponseListener -1024

kernel.finish_request

Event Class: FinishRequestEvent

The purpose of this event is to allow you to reset the global and environmental state of the application after a sub-request has finished (for example, the translator listener resets the translator's locale to the one of the parent request):

1
2
3
4
5
6
7
8
9
public function onKernelFinishRequest(FinishRequestEvent $event)
{
    if (null === $parentRequest = $this->requestStack->getParentRequest()) {
        return;
    }

    //Reset the locale of the subrequest to the locale of the parent request
    $this->setLocale($parentRequest);
}

These are the built-in Symfony listeners related to this event:

Listener Class Name Priority
LocaleListener 0
TranslatorListener 0
RouterListener 0
Firewall 0

kernel.terminate

Event Class: PostResponseEvent

The purpose of this event is to perform tasks after the response was already served to the client.

Read more on the kernel.terminate event.

This is the built-in Symfony listener related to this event:

Listener Class Name Priority
EmailSenderListener 0

kernel.exception

Event Class: GetResponseForExceptionEvent

The TwigBundle registers an ExceptionListener that forwards the Request to a given controller defined by the exception_listener.controller parameter.

A listener on this event can create and set a Response object, create and set a new Exception object, or do nothing:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;

public function onKernelException(GetResponseForExceptionEvent $event)
{
    $exception = $event->getException();
    $response = new Response();
    // setup the Response object based on the caught exception
    $event->setResponse($response);

    // you can alternatively set a new Exception
    // $exception = new \Exception('Some special exception');
    // $event->setException($exception);
}

Note

If you want to overwrite the status code (which you should do not without a good reason), set the X-Status-Code header:

1
2
3
4
5
6
7
$response = new Response(
    'Error',
    404, // this status code will be ignored
    array(
        'X-Status-Code' => 200 // this status code will actually be sent to the client
    )
);

If you do not set the X-Status-Code header, then Symfony uses the following logic to determine the status code:

  • If isClientError(), isServerError() or isRedirect() is true, then the status code on your Response object is used;
  • If the original exception implements HttpExceptionInterface, then getStatusCode() is called on the exception and used (the headers from getHeaders() are also added);
  • If both of the above aren't true, then a 500 status code is used.
Read more on the kernel.exception event.

These are the built-in Symfony listeners registered to this event:

Listener Class Name Priority
ProfilerListener 0
ExceptionListener -128

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.