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

Event Subscriber statt Listener

Event Subscriber statt Listener

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

Neben #[AsEventListener] aus den Kapiteln 35-36 gibt es einen zweiten Weg, auf Events zu reagieren: Event Subscriber. Funktional GLEICHWERTIG, aber mit einem strukturellen Unterschied, der bei MEHREREN Events pro Klasse relevant wird.

Das EventSubscriberInterface

src/EventListener/AktivitaetsSubscriber.php
<?php

declare(strict_types=1);

namespace App\EventListener;

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

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

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

    public function onAufgabeZugewiesen(AufgabeZugewiesenEvent $event): void
    {
        $this->logger->info('Aktivität: Aufgabe zugewiesen.');
    }

    public function onException(ExceptionEvent $event): void
    {
        $this->logger->info('Aktivität: Fehler aufgetreten.');
    }
}

getSubscribedEvents() ist eine STATISCHE Methode, die ZENTRAL auflistet, auf WELCHE Events diese Klasse reagiert UND welche Methode dafür jeweils zuständig ist – GENAU EIN Ort, um den gesamten "Zuständigkeitsbereich" der Klasse zu überblicken.

Listener vs. Subscriber: der strukturelle Unterschied

AnsatzStruktur
#[AsEventListener] (Kapitel 35-36)EINE Klasse = EIN Event (über den Typ des __invoke()-Parameters oder das event-Argument). Für ZWEI Events braucht man ZWEI Klassen ODER mehrere separate #[AsEventListener]-Attribute mit jeweils eigener Methode.
EventSubscriberInterface (dieses Kapitel)EINE Klasse kann MEHRERE Events auf EINMAL abonnieren, mit unterschiedlich benannten Methoden – die Zuordnung steht ZENTRAL in getSubscribedEvents().

Priorität bei Subscribern

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

Statt eines einzelnen Methodennamens ein Array [Methodenname, Priorität] – GENAU dieselbe Priorität-Logik wie bei #[AsEventListener] aus Kapitel 35, nur an anderer Stelle notiert.

Mehrere Methoden für dasselbe Event

public static function getSubscribedEvents(): array
{
    return [
        AufgabeZugewiesenEvent::class => [
            ['protokolliere', 10],
            ['sendeBenachrichtigung', 0],
        ],
    ];
}

Ein VERSCHACHTELTES Array ermöglicht mehrere Methoden für DASSELBE Event, jeweils mit eigener Priorität – ein Fall, den #[AsEventListener] pro Klasse NICHT abbilden kann (dort bräuchte man dafür mehrere Attribute auf verschiedenen Methoden).

Faustregel: wann Listener, wann Subscriber?

Tipp: #[AsEventListener] (Kapitel 35-36) für den HÄUFIGSTEN Fall: EINE Klasse reagiert auf EIN Event – knapper, direkt an der Methode sichtbar. EventSubscriberInterface (dieses Kapitel), sobald EINE Klasse THEMATISCH ZUSAMMENGEHÖRENDE Logik für MEHRERE Events bündeln soll (wie unser AktivitaetsSubscriber, der ALLE Aktivitäts-Protokollierung an EINEM Ort sammelt) – beide Ansätze sind gleichwertig registriert (Autoconfigure, Kapitel 34), die Wahl ist eine reine Strukturfrage.

Damit ist Block 6 (Services, Dependency Injection & Events) fast abgeschlossen! Ein letztes Kapitel fehlt noch: Kapitel 38 nutzt GENAU das Event aus diesem Block, um tatsächlich eine E-Mail zu versenden.