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

Das EventDispatcher-System

Das EventDispatcher-System

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

JEDE Symfony-Anfrage durchläuft bereits UNSICHTBAR ein Event-System – Zeit, es sichtbar zu machen, bevor wir in Kapitel 36 unsere EIGENEN Events dafür nutzen, Benachrichtigungen bei neuen Aufgaben-Zuweisungen auszulösen.

Was ist das Observer/EventDispatcher-Pattern?

Statt dass Code A DIREKT Code B aufruft (feste Kopplung), "sendet" Code A ein EREIGNIS in die Welt, OHNE zu wissen, WER (falls überhaupt jemand) darauf reagiert. Beliebig viele "Listener" können sich für DASSELBE Ereignis registrieren, OHNE dass der auslösende Code davon etwas mitbekommt – lose Kopplung als Kernvorteil.

Kernel Events: Symfonys eigene Events im Request-Lebenszyklus

JEDE HTTP-Anfrage löst eine FESTE Abfolge von Kernel-Events aus – dieselben Events, die INTERN dafür sorgen, dass z. B. die Firewall (Block 5) oder Fehlerseiten (Kapitel 41) funktionieren:

EventZeitpunkt
kernel.requestGanz am ANFANG, bevor der Controller läuft – hier greift z. B. die Security-Firewall ein.
kernel.controllerDirekt bevor der eigentliche Controller aufgerufen wird.
kernel.responseNACHDEM der Controller eine Response zurückgegeben hat, bevor sie ausgeliefert wird.
kernel.exceptionWenn während der Verarbeitung eine unbehandelte Exception auftritt – hier entstehen z. B. Fehlerseiten.
php bin/console debug:event-dispatcher

Zeigt ALLE registrierten Listener für JEDES Event, in der REIHENFOLGE ihrer Ausführung – unschätzbar wertvoll, um zu verstehen, WAS bei einer Anfrage tatsächlich passiert, besonders bei mehreren installierten Bundles.

Ein einfacher Listener für kernel.exception

src/EventListener/ExceptionListener.php
<?php

declare(strict_types=1);

namespace App\EventListener;

use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;

#[AsEventListener(event: 'kernel.exception')]
class ExceptionListener
{
    public function __construct(
        private readonly LoggerInterface $logger,
    ) {
    }

    public function __invoke(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();

        $this->logger->critical('Unbehandelte Exception: ' . $exception->getMessage());
    }
}

#[AsEventListener] registriert diese Klasse AUTOMATISCH dank autoconfigure: true (Kapitel 34) – KEIN manueller Eintrag in services.yaml nötig. __invoke() macht die Klasse selbst "aufrufbar" wie eine Funktion – ein gängiges PHP-Muster für Klassen mit GENAU EINER Kernaufgabe.

Das Event-Objekt: Träger von Kontext UND Steuerung

ExceptionEvent trägt nicht nur INFORMATIONEN (die geworfene Exception), sondern erlaubt Listenern auch, das WEITERE Verhalten zu BEEINFLUSSEN:

use Symfony\Component\HttpFoundation\Response;

public function __invoke(ExceptionEvent $event): void
{
    $exception = $event->getThrowable();

    if ($exception instanceof \App\Exception\ProjectLimitExceededException) {
        $event->setResponse(new Response('Projekt-Limit erreicht.', 429));
    }
}

setResponse() ÜBERSCHREIBT die Standard-Fehlerbehandlung mit einer eigenen Antwort – ein mächtiges Werkzeug, das wir bewusst NUR am Rande erwähnen, da eigene Business-Events (Kapitel 36) für die MEISTEN Anwendungsfälle die bessere Wahl sind.

Priorität, wenn mehrere Listener auf DASSELBE Event reagieren

#[AsEventListener(event: 'kernel.exception', priority: 10)]
class HochPrioritaetsListener { /* läuft ZUERST */ }

#[AsEventListener(event: 'kernel.exception', priority: -10)]
class NiedrigePrioritaetsListener { /* läuft ZULETZT */ }

HÖHERE Priorität läuft ZUERST (Standard: 0) – wichtig, wenn die Reihenfolge mehrerer Listener für DASSELBE Event tatsächlich eine Rolle spielt, etwa wenn ein Listener die Verarbeitung für nachfolgende Listener stoppen können soll.

Tipp: Kernel Events sind das FUNDAMENT, auf dem VIELE Symfony-Bundles selbst aufbauen (Security, Routing, sogar Twig-Rendering) – für unsere EIGENE Geschäftslogik (Aufgaben-Zuweisung, Kapitel 36) bauen wir stattdessen EIGENE, benannte Events, GENAU nach demselben Muster.