Whatsapp Telegram Telegram Call Anrufen

Event Dispatcher und Event Subscriber in Symfony


Die EventDispatcher-Komponente von Symfony ermöglicht die Kommunikation zwischen verschiedenen Teilen einer Anwendung durch das Versenden und Empfangen von Ereignissen. Dies fördert eine lose Kopplung und erhöht die Flexibilität und Erweiterbarkeit Ihrer Anwendung.

In diesem Artikel werden wir die folgenden Themen ausführlich behandeln:

  1. Einführung in die EventDispatcher-Komponente
  2. Eingebaute Symfony-Ereignisse
  3. Erstellen benutzerdefinierter Ereignisse
  4. Event Listener vs. Event Subscriber
  5. Praktische Anwendungsfälle

1. Einführung in die EventDispatcher-Komponente

1.1 Was ist der Event Dispatcher?

Der Event Dispatcher ist ein zentraler Bestandteil des Observer-Patterns, der es ermöglicht, dass verschiedene Teile einer Anwendung miteinander kommunizieren, ohne direkt voneinander abhängig zu sein. Komponenten können Ereignisse auslösen, auf die andere Komponenten mit Listenern oder Subscribern reagieren können.

1.2 Vorteile der Verwendung von Ereignissen

  • Lose Kopplung: Komponenten müssen nicht direkt miteinander kommunizieren.
  • Erweiterbarkeit: Neue Funktionalitäten können hinzugefügt werden, indem auf bestehende Ereignisse reagiert wird.
  • Wartbarkeit: Änderungen an einem Teil der Anwendung beeinflussen nicht direkt andere Teile.

1.3 Installation der EventDispatcher-Komponente

Falls nicht bereits installiert, können Sie die Komponente mit Composer hinzufügen:

composer require symfony/event-dispatcher

2. Eingebaute Symfony-Ereignisse

Symfony löst viele Ereignisse während des Anfrage-/Antwortzyklus aus, auf die Sie reagieren können.

2.1 Kern-Ereignisse

  • Kernel Events: Ereignisse, die vom HttpKernel ausgelöst werden.
    • kernel.request: Bevor die Anfrage verarbeitet wird.
    • kernel.controller: Bevor der Controller aufgerufen wird.
    • kernel.response: Bevor die Antwort gesendet wird.
    • kernel.exception: Wenn eine Ausnahme auftritt.
    • kernel.terminate: Nach dem Senden der Antwort (für Hintergrundaufgaben).

2.2 Beispiel: Verwenden des kernel.request-Ereignisses

Schritt 1: Erstellen eines Event Listeners

// src/EventListener/RequestLoggerListener.php

namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\RequestEvent;
use Psr\Log\LoggerInterface;

class RequestLoggerListener
{
    private LoggerInterface $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function onKernelRequest(RequestEvent $event)
    {
        $request = $event->getRequest();
        $this->logger->info('Neue Anfrage: ' . $request->getUri());
    }
}

Schritt 2: Registrieren des Event Listeners

In Ihrer services.yaml:

# config/services.yaml

services:
    App\EventListener\RequestLoggerListener:
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

2.3 Prioritäten von Ereignissen

Sie können die Priorität eines Event Listeners festlegen, um zu bestimmen, in welcher Reihenfolge die Listener ausgeführt werden. Höhere Zahlen haben höhere Priorität.

- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 10 }

3. Erstellen benutzerdefinierter Ereignisse

Neben den eingebauten Ereignissen können Sie eigene Ereignisse definieren und auslösen.

3.1 Erstellen einer benutzerdefinierten Ereignisklasse

Beispiel:

Angenommen, Sie möchten ein Ereignis auslösen, wenn ein Benutzer registriert wird.

// src/Event/UserRegisteredEvent.php

namespace App\Event;

use App\Entity\User;
use Symfony\Contracts\EventDispatcher\Event;

class UserRegisteredEvent extends Event
{
    public const NAME = 'user.registered';

    private User $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function getUser(): User
    {
        return $this->user;
    }
}

3.2 Auslösen des Ereignisses

In Ihrem Controller oder Service:

// src/Controller/RegistrationController.php

namespace App\Controller;

use App\Entity\User;
use App\Event\UserRegisteredEvent;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class RegistrationController extends AbstractController
{
    #[Route('/register', name: 'user_register')]
    public function register(
        Request $request,
        EntityManagerInterface $entityManager,
        EventDispatcherInterface $eventDispatcher
    ): Response {
        // Annahme: Formularverarbeitung und Benutzererstellung sind hier implementiert
        $user = new User();
        // ... Formularverarbeitung ...

        // Benutzer speichern
        $entityManager->persist($user);
        $entityManager->flush();

        // Ereignis auslösen
        $event = new UserRegisteredEvent($user);
        $eventDispatcher->dispatch($event, UserRegisteredEvent::NAME);

        return new Response('Benutzer registriert!');
    }
}

3.3 Erstellen eines Event Listeners für das benutzerdefinierte Ereignis

// src/EventListener/WelcomeEmailListener.php

namespace App\EventListener;

use App\Event\UserRegisteredEvent;
use App\Service\MailerService;

class WelcomeEmailListener
{
    private MailerService $mailer;

    public function __construct(MailerService $mailer)
    {
        $this->mailer = $mailer;
    }

    public function onUserRegistered(UserRegisteredEvent $event)
    {
        $user = $event->getUser();
        $this->mailer->sendWelcomeEmail($user);
    }
}

Registrieren des Event Listeners:

# config/services.yaml

services:
    App\EventListener\WelcomeEmailListener:
        tags:
            - { name: kernel.event_listener, event: user.registered, method: onUserRegistered }

4. Event Listener vs. Event Subscriber

4.1 Event Listener

  • Definition: Eine Klasse oder Funktion, die auf ein bestimmtes Ereignis reagiert.
  • Registrierung: Direkt in der Service-Konfiguration, wobei das Ereignis und die Methode angegeben werden.
  • Vorteil: Einfach zu implementieren für einzelne Ereignisse.

Beispiel:

Siehe WelcomeEmailListener oben.

4.2 Event Subscriber

  • Definition: Eine Klasse, die mehrere Ereignisse abonniert und die entsprechenden Methoden bereitstellt.
  • Implementierung: Implementiert das EventSubscriberInterface.
  • Vorteil: Besser organisiert, wenn eine Klasse auf mehrere Ereignisse reagieren soll.

Beispiel eines Event Subscribers:

// src/EventSubscriber/UserActivitySubscriber.php

namespace App\EventSubscriber;

use App\Event\UserRegisteredEvent;
use App\Event\UserDeletedEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class UserActivitySubscriber implements EventSubscriberInterface
{
    private LoggerInterface $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            UserRegisteredEvent::NAME => 'onUserRegistered',
            UserDeletedEvent::NAME => 'onUserDeleted',
        ];
    }

    public function onUserRegistered(UserRegisteredEvent $event)
    {
        $user = $event->getUser();
        $this->logger->info('Neuer Benutzer registriert: ' . $user->getEmail());
    }

    public function onUserDeleted(UserDeletedEvent $event)
    {
        $user = $event->getUser();
        $this->logger->info('Benutzer gelöscht: ' . $user->getEmail());
    }
}

Registrieren des Event Subscribers:

# config/services.yaml

services:
    App\EventSubscriber\UserActivitySubscriber:
        tags:
            - { name: kernel.event_subscriber }

4.3 Unterschiede zwischen Listener und Subscriber

  • Event Listener:

    • Reagiert auf ein spezifisches Ereignis.
    • Wird in der Service-Konfiguration registriert.
    • Einfach für einzelne Ereignisse.
  • Event Subscriber:

    • Kann mehrere Ereignisse abonnieren.
    • Implementiert EventSubscriberInterface.
    • Bessere Organisation bei mehreren Ereignissen.

5. Praktische Anwendungsfälle

5.1 Senden von Benachrichtigungen

  • Anwendung: Senden von E-Mails oder Push-Benachrichtigungen, wenn bestimmte Aktionen stattfinden (z. B. neue Bestellung, Passwortänderung).
  • Implementierung: Erstellen eines Ereignisses und eines entsprechenden Listeners oder Subscribers, der die Benachrichtigung sendet.

5.2 Protokollierung und Monitoring

  • Anwendung: Protokollieren von Benutzeraktivitäten, Ausnahmen oder Systemereignissen.
  • Implementierung: Listener oder Subscriber, die auf Ereignisse wie kernel.exception reagieren und die Informationen protokollieren.

5.3 Modifikation von Anfragen und Antworten

  • Anwendung: Hinzufügen von Headern zu Antworten, Umleiten von Anfragen, Modifizieren von Inhalten.
  • Implementierung: Verwenden von Kernel-Ereignissen wie kernel.request, kernel.response.

Beispiel: Hinzufügen eines Sicherheits-Headers

// src/EventSubscriber/SecurityHeaderSubscriber.php

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

class SecurityHeaderSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            'kernel.response' => 'onKernelResponse',
        ];
    }

    public function onKernelResponse(ResponseEvent $event)
    {
        $response = $event->getResponse();
        $response->headers->set('X-Frame-Options', 'DENY');
    }
}

5.4 Validierung und Authentifizierung

  • Anwendung: Validieren von Anfragen, Überprüfen von Berechtigungen.
  • Implementierung: Listener für kernel.controller oder kernel.request, die vor der Ausführung des Controllers bestimmte Checks durchführen.

5.5 Caching und Performance

  • Anwendung: Implementieren von Caching-Mechanismen, um die Performance zu verbessern.
  • Implementierung: Listener oder Subscriber, die Inhalte zwischenspeichern oder aus dem Cache liefern.

Zusammenfassung

  • Event Dispatcher: Ermöglicht die Kommunikation zwischen verschiedenen Teilen der Anwendung durch Ereignisse.
  • Eingebaute Ereignisse: Symfony stellt viele Ereignisse bereit, auf die Sie reagieren können.
  • Benutzerdefinierte Ereignisse: Sie können eigene Ereignisse erstellen, um auf spezifische Aktionen zu reagieren.
  • Event Listener vs. Subscriber: Listener reagieren auf einzelne Ereignisse, Subscriber können mehrere Ereignisse abonnieren.
  • Praktische Anwendungsfälle: Benachrichtigungen, Protokollierung, Anfrage-/Antwort-Modifikation, Validierung, Caching.

Weiterführende Ressourcen

EventDispatcher Component

Event Listeners und Subscribers


CEO Image

Ali Ajjoub

info@ajjoub.com

Adresse 0049-15773651670

Adresse Jacob-winter-platz,1 01239 Dresden

Buchen Sie jetzt Ihren Termin für eine umfassende und individuelle Beratung.

Termin Buchen

Kontaktieren Sie uns

Lassen Sie uns K o n t a k t aufnehmen!