Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Event Subscribers Instead of Listeners

Event Subscribers Instead of Listeners

~13 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

Besides #[AsEventListener] from chapters 35-36, there's a second way to react to events: event subscribers. Functionally EQUIVALENT, but with a structural difference that matters for MULTIPLE events per class.

The EventSubscriberInterface

src/EventListener/ActivitySubscriber.php
<?php

declare(strict_types=1);

namespace App\EventListener;

use App\Event\TaskAssignedEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;

class ActivitySubscriber implements EventSubscriberInterface
{
    public function __construct(
        private readonly LoggerInterface $logger,
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [
            TaskAssignedEvent::class => 'onTaskAssigned',
            'kernel.exception' => 'onException',
        ];
    }

    public function onTaskAssigned(TaskAssignedEvent $event): void
    {
        $this->logger->info('Activity: task assigned.');
    }

    public function onException(ExceptionEvent $event): void
    {
        $this->logger->info('Activity: an error occurred.');
    }
}

getSubscribedEvents() is a STATIC method that CENTRALLY lists WHICH events this class reacts to AND which method handles each one – EXACTLY ONE place to get an overview of the class's entire "area of responsibility".

Listener vs. subscriber: the structural difference

ApproachStructure
#[AsEventListener] (chapters 35-36)ONE class = ONE event (via the __invoke() parameter's type or the event argument). For TWO events, you need TWO classes OR several separate #[AsEventListener] attributes, each on its own method.
EventSubscriberInterface (this chapter)ONE class can subscribe to SEVERAL events AT ONCE, with differently named methods – the mapping sits CENTRALLY in getSubscribedEvents().

Priority with subscribers

public static function getSubscribedEvents(): array
{
    return [
        TaskAssignedEvent::class => ['onTaskAssigned', 10],
        'kernel.exception' => ['onException', -10],
    ];
}

An array [methodName, priority] instead of a single method name – EXACTLY the same priority logic as #[AsEventListener] from chapter 35, just noted in a different place.

Multiple methods for the same event

public static function getSubscribedEvents(): array
{
    return [
        TaskAssignedEvent::class => [
            ['log', 10],
            ['sendNotification', 0],
        ],
    ];
}

A NESTED array allows several methods for the SAME event, each with its own priority – a case #[AsEventListener] per class CAN'T represent (you'd need several attributes on different methods for that).

Rule of thumb: when a listener, when a subscriber?

Tipp: #[AsEventListener] (chapters 35-36) for the MOST COMMON case: ONE class reacts to ONE event – terser, directly visible on the method. EventSubscriberInterface (this chapter), once ONE class should bundle THEMATICALLY RELATED logic for SEVERAL events (like our ActivitySubscriber, which collects ALL activity logging in ONE place) – both approaches are registered equally (autoconfigure, chapter 34), the choice is purely a structural question.

With that, block 6 (services, dependency injection & events) is almost complete! One last chapter remains: chapter 38 uses EXACTLY the event from this block to actually send an email.