Part 2: EventDispatcher in Drupal (Spotlight on Symfony in Drupal)

In Part 2 of our exploration of Symfony components in Drupal, we focus on the event dispatcher.

Spotlight on Symfony in Drupal

  1. Part 1: HttpKernel in Drupal
  2. Part 2: EventDispatcher in Drupal
  3. Part 3: Routing in Drupal
  4. Part 4: Utility Components in Drupal

The event dispatcher is a tool that enables the application to communicate across objects by subscribing to and listening for events. It achieves this by creating a directory for various event types, and the corresponding registered listeners for each event type. When a specific type of event occurs, the code that has registered a listener for that event is invoked. If you're familiar with the Mediator and Observer design patterns you might recognize similarities here.

Symfony's EventDispatcher component in Drupal

When Drupal receives and incoming request, the HttpKernel eventually executes this code:

$event = new RequestEvent($this, $request, $type);
$this->dispatcher->dispatch($event, KernelEvents::REQUEST);

This code dispatches RequestEvent to the EventDispatcher component, along with the $request object.

Find the code for the EventDispatcher in the vendor/symfony/event-dispatcher/ directory. Let's examine the EventDispatcher.php file in that directory. It contains the class that makes up the core of this component.

The event dispatcher includes methods for adding and removing both listeners and subscribers. It has a dispatch() method that is responsible for collecting and invoking registered listeners for a particular event.

    public function dispatch(object $event, string $eventName = null): object
    {
        $eventName ??= $event::class;

        if (isset($this->optimized)) {
            $listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? [] : $this->optimizeListeners($eventName));
        } else {
            $listeners = $this->getListeners($eventName);
        }

        if ($listeners) {
            $this->callListeners($listeners, $eventName, $event);
        }

        return $event;
    }

Tip: This code uses ??=, PHP's null coalescing assignment operator.

The callListeners method executes the code that has been registered for a specific event.

Drupal's ContainerAwareEventDispatcher class

Drupal optimizes the performance of Symfony's EventDispatcher component. Drupal's customized version, Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher, runs an initial compilation step which prepares a list of all event listeners and subscribers and stores them in an optimized fashion. Drupal's version is faster by an order of magnitude due to these customizations!

Apart from this additional compiler pass, the 2 components are highly similar.

Learn more

Next up

Stay tuned for our next article in this Spotlight on Symfony series: the Routing component.

Related Topics

Add new comment

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <code class> <ul type> <ol start type> <li> <dl> <dt> <dd><h3 id> <p>
  • Lines and paragraphs break automatically.

About us

Drupalize.Me is the best resource for learning Drupal online. We have an extensive library covering multiple versions of Drupal and we are the most accurate and up-to-date Drupal resource. Learn more