Reading list Switch to dark mode

    Custom Events and Event Subscribers in Symfony

    Updated 13 March 2022

    In this blog we are going to discuss Custom Events and Event Subscribers in Symfony.

    What is an Event?

    In general, Something that happens is an event. If we take an example of an eccomerce system the below are some events:

    • Create product
    • Update Product
    • Delete Product
    • Order Create

    .. and many more
    So these are the events examples in an eCommerce system.

    Symfony built-in Events

    In Symfony there are several events are already created. For example:

    HttpKernel component events: You can use these events to modify handling of request and the response return process.

    Searching for an experienced
    Symfony Company ?
    Find out More
    • kernel.request
    • kernel.response
    • kernel.terminate

    and many others (https://symfony.com/doc/current/reference/events.html)

    Now we will understand the event subscribe process step by step.

    1. install EventDispatcher Component

    To create, dispatch and subscribe events in symfony, “event-dispatcher” component must installed.
    This component provides tools for :

    • Your application components can Dispatch events and communicate with each other.
    • Listening to the events.

    To install EventDispatcher Component with composer run below command :

    composer require symfony/event-dispatcher

    So EventDispatcher now installed on your symfony application.

    Further, we will create a custom event.

    2. Create Custom Event

    In Symfony, you can also create your own custom events.
    To create an event you have to create event class in src/Event folder.
    Lets create an event for product creation :

    // src/ProductCreateEvent.php
    
    <?php
    
    namespace Product\Event;
    
    use Symfony\Contracts\EventDispatcher\Event;
    
    class ProductCreateEvent extends Event
    {
        public const NAME = 'product.created';
    
        // ....
    }

    That’s it. Our event for product creation is created.
    likewise, you can create ProductUpdateEvent and ProductDeleteEvent events for Product Updation and product deletion.

    Further, we will create subscriber for the event.

    3. Create EventSubscriber

    An event subscriber is a method that listens for a specific event that is raised by an event publisher.
    In this step, we will create an event subscriber for the Product Create Event.
    event subscriber class is a PHP class which:

    • Has to implements the EventSubscriberInterface interface.
    • Tells the dispatcher for which events event subscriber is subscribed.
    • Requires a static getSubscribedEvents() method. The dispatcher automatically registers subscriber for every event returned by this method. It returns an array indexed by event name and value by method name to call

    Create event subscriber class in “src/Event” folder.

    Lets create an event subscriber for product creation events :

    // src/Event/ProductEventSubscriber.php
    
    <?php
    
    namespace Product\Event;
    
    use Product\Event\ProductCreateEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpKernel\Event\ResponseEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    class ProductEventSubscriber implements EventSubscriberInterface
    {
        // Returns an array indexed by event name and value by method name to call
        public static function getSubscribedEvents()
        {
            return [
                ProductCreateEvent::NAME => 'onProductCreation',
                //hook multiple functions with the events with priority for sequence of function calls
                ProductUpdateEvent::NAME => [
                    ['onProductCreation', 1],
                    ['onProductUpdation', 2],
                ],
                ProductDeleteEvent::NAME => 'onProductDeletion',
                KernelEvents::RESPONSE => 'onKernelResponse',
            ];
        }
    
        public function onProductCreation(ProductCreateEvent $event)
        {
            // write code to execute on product creation event
        }
    
        public function onProductUpdation(ProductUpdateEvent $event)
        {
            // write code to execute on product updation event
        }
    
        public function onProductDeletion(ProductDeleteEvent $event)
        {
            // write code to execute on product deletion event
        }
    
        public function onKernelResponse(ResponseEvent  $event)
        {
            // write code to execute on in-built Kernel Response event
        }
    }

    In the above example, we have subscribed for some custom product events and also an in-built event KernelEvents::RESPONSE

    Next, we have to add subscriber before dispatching the event in our code.

    4. Add Subscriber and dispatching event

    Now how we will add the above created subscriber to the events so that whenever the event occur, our subscriber will be invoked and our desired code can be executed for the event?
    The answer is addSubscriber() method: We have to call this method to register subscriber with the dispatcher. We have to pass the event subscriber object in the parameter of this function.
    in our example, we have passed ProductEventSubscriber class object to in this function.

    Now we have to dispatch the event.

    The dispatch() method : Through this function all the listener of the event will get notified. This methods takes two parameters-

    • First is the object of the event class for which you have subscribed. In our example we are subscribing for new ProductCreateEvent().
    • Second is the name of the event. So that specific method can be called for the event. In our example we are passing the name of product create event by ProductCreateEvent::NAME.

    Lets call this methods in our controller.

    // src/controller/ProductController.php
    
    <?php
    
    namespace App\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;
    
    use Symfony\Component\EventDispatcher\EventDispatcherInterface;
    use Product\Event\ProductCreateEvent;
    use Product\Event\ProductEventSubscriber;
    
    class ProductController extends AbstractController
    {
        public function __construct(EventDispatcherInterface $eventDispatcher)
        {
            $this->eventDispatcher = $eventDispatcher;
        }
    
        /**
         * @Route("/products/new")
         */
        public function new(): Response
        {
            $event = new ProductCreateEvent();
            
            $this->eventDispatcher->addSubscriber(new ProductEventSubscriber());
    
            $this->eventDispatcher->dispatch($event, ProductCreateEvent::NAME);
    
            return new Response('Return your response here.');
        }
    }

    In the above example we registered our subscriber by using addSubscriber() method on the dispatcher.

    We can also do this by using services.yaml and you can register your subscribers in services.yaml.
    Lets add our product.created event subscriber:

    // config/services.yaml
    services:
        Product\Event\ProductEventSubscriber:
            tags:
                - { name: kernel.event_subscriber, event: product.created }

    So in the above ProductController example, we have subscribed (with addSubscriber()) and dispatched(with dispatch()) the event.
    This is all for creating an event and listen to that event using event subscribers in Symfony.

    So this is all the process to create custom events in Symfony and listen to those events by the use of Event Subscribers using event-dispatcher component.

    Hope this blog will help you using event dispatcher in your application.

    Thanks for reading. Happy coding.🙂

    . . .

    Leave a Comment

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


    1 comments

  • Sheila
    Great article, exactly what I needed.
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home