Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. Cookbook
  4. Event Dispatcher
  5. How to Create Event Listeners and Subscribers
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Creating an Event Listener
  • Creating an Event Subscriber
  • Request Events, Checking Types
  • Listeners or Subscribers

How to Create Event Listeners and Subscribers

Edit this page

Warning: You are browsing the documentation for Symfony 2.3, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

How to Create Event Listeners and Subscribers

During the execution of a Symfony application, lots of event notifications are triggered. Your application can listen to these notifications and respond to them by executing any piece of code.

Internal events provided by Symfony itself are defined in the KernelEvents class. Third-party bundles and libraries also trigger lots of events and your own application can trigger custom events.

All the examples shown in this article use the same KernelEvents::EXCEPTION event for consistency purposes. In your own application, you can use any event and even mix several of them in the same subscriber.

Creating an Event Listener

The most common way to listen to an event is to register an event listener:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// src/AppBundle/EventListener/ExceptionListener.php
namespace AppBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

class ExceptionListener
{
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        // You get the exception object from the received event
        $exception = $event->getException();
        $message = sprintf(
            'My Error says: %s with code: %s',
            $exception->getMessage(),
            $exception->getCode()
        );

        // Customize your response object to display the exception details
        $response = new Response();
        $response->setContent($message);

        // HttpExceptionInterface is a special type of exception that
        // holds status code and header details
        if ($exception instanceof HttpExceptionInterface) {
            $response->setStatusCode($exception->getStatusCode());
            $response->headers->replace($exception->getHeaders());
        } else {
            $response->setStatusCode(500);
        }

        // Send the modified response object to the event
        $event->setResponse($response);
    }
}

Tip

Each event receives a slightly different type of $event object. For the kernel.exception event, it is GetResponseForExceptionEvent. To see what type of object each event listener receives, see KernelEvents or the documentation about the specific even you're listening to.

Now that the class is created, you just need to register it as a service and notify Symfony that it is a "listener" on the kernel.exception event by using a special "tag":

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# app/config/services.yml
services:
    app.exception_listener:
        class: AppBundle\EventListener\ExceptionListener
        tags:
            - { name: kernel.event_listener, event: kernel.exception }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<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="app.exception_listener"
            class="AppBundle\EventListener\ExceptionListener">

            <tag name="kernel.event_listener" event="kernel.exception" />
        </service>
    </services>
</container>
1
2
3
4
5
// app/config/services.php
$container
    ->register('app.exception_listener', 'AppBundle\EventListener\ExceptionListener')
    ->addTag('kernel.event_listener', array('event' => 'kernel.exception'))
;

Note

There is an optional tag attribute called method which defines which method to execute when the event is triggered. By default the name of the method is on + "camel-cased event name". If the event is kernel.exception the method executed by default is onKernelException().

The other optional tag attribute is called priority, which defaults to 0 and it controls the order in which listeners are executed (the highest the priority, the earlier a listener is executed). This is useful when you need to guarantee that one listener is executed before another. The priorities of the internal Symfony listeners usually range from -255 to 255 but your own listeners can use any positive or negative integer.

Creating an Event Subscriber

Another way to listen to events is via an event subscriber, which is a class that defines one or more methods that listen to one or various events. The main difference with the event listeners is that subscribers always know which events they are listening to.

In a given subscriber, different methods can listen to the same event. The order in which methods are executed is defined by the priority parameter of each method (the higher the priority the earlier the method is called). To learn more about event subscribers, read The EventDispatcher Component.

The following example shows an event subscriber that defines several methods which listen to the same kernel.exception event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// src/AppBundle/EventSubscriber/ExceptionSubscriber.php
namespace AppBundle\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class ExceptionSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return array(
           KernelEvents::EXCEPTION => array(
               array('processException', 10),
               array('logException', 0),
               array('notifyException', -10),
           )
        );
    }

    public function processException(GetResponseForExceptionEvent $event)
    {
        // ...
    }

    public function logException(GetResponseForExceptionEvent $event)
    {
        // ...
    }

    public function notifyException(GetResponseForExceptionEvent $event)
    {
        // ...
    }
}

Now, you just need to register the class as a service and add the kernel.event_subscriber tag to tell Symfony that this is an event subscriber:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# app/config/services.yml
services:
    app.exception_subscriber:
        class: AppBundle\EventSubscriber\ExceptionSubscriber
        tags:
            - { name: kernel.event_subscriber }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<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="app.exception_subscriber"
            class="AppBundle\EventSubscriber\ExceptionSubscriber">

            <tag name="kernel.event_subscriber"/>
        </service>
    </services>
</container>
1
2
3
4
5
6
7
8
// app/config/services.php
$container
    ->register(
        'app.exception_subscriber',
        'AppBundle\EventSubscriber\ExceptionSubscriber'
    )
    ->addTag('kernel.event_subscriber')
;

Request Events, Checking Types

A single page can make several requests (one master request, and then multiple sub-requests - typically by Creating and Using Templates). For the core Symfony events, you might need to check to see if the event is for a "master" request or a "sub request":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/AppBundle/EventListener/RequestListener.php
namespace AppBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class RequestListener
{
    public function onKernelRequest(GetResponseEvent $event)
    {
        if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
            // don't do anything if it's not the master request
            return;
        }

        // ...
    }
}

Certain things, like checking information on the real request, may not need to be done on the sub-request listeners.

Listeners or Subscribers

Listeners and subscribers can be used in the same application indistinctly. The decision to use either of them is usually a matter of personal taste. However, there are some minor advantages for each of them:

  • Subscribers are easier to reuse because the knowledge of the events is kept in the class rather than in the service definition. This is the reason why Symfony uses subscribers internally;
  • Listeners are more flexible because bundles can enable or disable each of them conditionally depending on some configuration value.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    Symfony Code Performance Profiling

    Symfony Code Performance Profiling

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of Philipp Bräutigam, a Symfony contributor

    Thanks Philipp Bräutigam for being a Symfony contributor

    1 commit • 2 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Algolia