Laravel Events und Listeners 2026: Event-Driven Architecture und Interview-Fragen

Umfassender Leitfaden zu Laravel Events und Listeners in 2026. Event-Driven Architecture, Observer Pattern, Broadcasting und häufige Interview-Fragen mit Codebeispielen.

Laravel Events und Listeners Event-Driven Architecture Diagram

Das Event-System von Laravel bildet das Rückgrat einer sauberen, entkoppelten Anwendungsarchitektur. In einer Zeit, in der Microservices und asynchrone Verarbeitung zum Standard gehören, ermöglichen Events und Listeners eine flexible Kommunikation zwischen verschiedenen Teilen einer Anwendung. Laravel 12 hat das Event-System weiter verfeinert und bietet mit typed Events, verbessertem Broadcasting und nativer Queue-Integration leistungsstarke Werkzeuge für moderne Webanwendungen. Dieser Artikel behandelt die Grundlagen von Laravel Events, fortgeschrittene Patterns und die häufigsten Interview-Fragen zu diesem Thema.

Events entkoppeln Geschäftslogik

Das Observer Pattern, das Laravel Events zugrunde liegt, ermöglicht es, auf Aktionen zu reagieren, ohne den auslösenden Code direkt zu modifizieren. Wenn ein Benutzer sich registriert, kann ein Event ausgelöst werden, auf das mehrere Listener reagieren: E-Mail-Versand, Analytics-Tracking, CRM-Synchronisation. Der Registrierungscode bleibt dabei schlank und fokussiert.

Events und Listeners erstellen

Laravel bietet Artisan-Befehle zur schnellen Generierung von Events und Listeners. Ein Event repräsentiert eine Aktion, die in der Anwendung stattgefunden hat, während ein Listener auf dieses Event reagiert und entsprechende Aktionen ausführt.

bash
php artisan make:event OrderPlaced
php artisan make:listener SendOrderConfirmation --event=OrderPlaced
php artisan make:listener UpdateInventory --event=OrderPlaced
php artisan make:listener NotifyWarehouse --event=OrderPlaced

Die Event-Klasse enthält die relevanten Daten, die an alle Listener weitergegeben werden. Laravel 12 unterstützt typed Properties und Constructor Property Promotion für prägnanten Code.

php
<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderPlaced
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public Order $order,
        public float $totalAmount,
        public string $currency = 'EUR'
    ) {}
}

Der zugehörige Listener implementiert die handle-Methode, die das Event als Parameter erhält. Die Typdeklaration ermöglicht IDE-Autovervollständigung und statische Analyse.

php
<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use App\Mail\OrderConfirmation;
use Illuminate\Support\Facades\Mail;

class SendOrderConfirmation
{
    public function handle(OrderPlaced $event): void
    {
        Mail::to($event->order->user->email)
            ->queue(new OrderConfirmation($event->order));
    }
}

Event-Registrierung und Auto-Discovery

Laravel 12 bietet zwei Methoden zur Registrierung von Events: explizite Registrierung im EventServiceProvider und automatische Discovery. Die explizite Methode bietet mehr Kontrolle und Übersichtlichkeit.

php
<?php

namespace App\Providers;

use App\Events\OrderPlaced;
use App\Events\PaymentProcessed;
use App\Listeners\NotifyWarehouse;
use App\Listeners\SendOrderConfirmation;
use App\Listeners\UpdateInventory;
use App\Listeners\SendPaymentReceipt;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        OrderPlaced::class => [
            SendOrderConfirmation::class,
            UpdateInventory::class,
            NotifyWarehouse::class,
        ],
        PaymentProcessed::class => [
            SendPaymentReceipt::class,
        ],
    ];

    public function shouldDiscoverEvents(): bool
    {
        return false; // Explicit registration preferred
    }
}

Für automatische Discovery analysiert Laravel die Listener-Klassen und ermittelt anhand der handle-Methodensignatur, auf welche Events sie reagieren. Diese Methode eignet sich für kleinere Projekte oder schnelles Prototyping.

php
public function shouldDiscoverEvents(): bool
{
    return true;
}

protected function discoverEventsWithin(): array
{
    return [
        $this->app->path('Listeners'),
        $this->app->path('Modules/Orders/Listeners'),
    ];
}

Queued Listeners für asynchrone Verarbeitung

Zeitkritische Operationen wie E-Mail-Versand oder externe API-Aufrufe sollten nicht synchron verarbeitet werden. Durch Implementierung des ShouldQueue-Interface werden Listeners automatisch in die Queue eingereiht.

php
<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use App\Services\InventoryService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class UpdateInventory implements ShouldQueue
{
    use InteractsWithQueue;

    public string $queue = 'inventory';
    public int $tries = 3;
    public int $backoff = 60;

    public function __construct(
        private InventoryService $inventoryService
    ) {}

    public function handle(OrderPlaced $event): void
    {
        foreach ($event->order->items as $item) {
            $this->inventoryService->decrementStock(
                $item->product_id,
                $item->quantity
            );
        }
    }

    public function failed(OrderPlaced $event, \Throwable $exception): void
    {
        // Log failure, notify admin, trigger compensating action
        logger()->error('Inventory update failed', [
            'order_id' => $event->order->id,
            'error' => $exception->getMessage(),
        ]);
    }
}

Die Konfiguration von Queue, Retry-Versuchen und Backoff-Zeit ermöglicht eine robuste Fehlerbehandlung. Die failed-Methode wird aufgerufen, wenn alle Retry-Versuche fehlgeschlagen sind.

Model Events und Observers

Eloquent-Models dispatchen automatisch Events bei CRUD-Operationen. Diese Model Events ermöglichen es, auf Datenbankänderungen zu reagieren, ohne den Controller-Code zu modifizieren.

php
<?php

namespace App\Models;

use App\Events\OrderPlaced;
use App\Observers\OrderObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Model;

#[ObservedBy(OrderObserver::class)]
class Order extends Model
{
    protected $dispatchesEvents = [
        'created' => OrderPlaced::class,
    ];
}

Observer-Klassen bündeln alle Event-Handler für ein Model an einem zentralen Ort. Laravel 12 unterstützt das ObservedBy-Attribut für eine deklarative Registrierung.

php
<?php

namespace App\Observers;

use App\Models\Order;
use App\Services\AuditLogService;

class OrderObserver
{
    public function __construct(
        private AuditLogService $auditLog
    ) {}

    public function creating(Order $order): void
    {
        $order->order_number = $this->generateOrderNumber();
    }

    public function created(Order $order): void
    {
        $this->auditLog->log('order.created', $order);
    }

    public function updating(Order $order): void
    {
        if ($order->isDirty('status')) {
            $order->status_changed_at = now();
        }
    }

    public function deleted(Order $order): void
    {
        $this->auditLog->log('order.deleted', $order);
    }

    private function generateOrderNumber(): string
    {
        return 'ORD-' . date('Ymd') . '-' . strtoupper(uniqid());
    }
}

Event Broadcasting für Echtzeit-Updates

Laravel Broadcasting ermöglicht die Übertragung von serverseitigen Events an Frontend-Clients über WebSockets. Dies ist essentiell für Echtzeit-Dashboards, Chat-Anwendungen und Live-Benachrichtigungen.

php
<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderStatusUpdated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public Order $order,
        public string $previousStatus,
        public string $newStatus
    ) {}

    public function broadcastOn(): array
    {
        return [
            new PrivateChannel('orders.' . $this->order->user_id),
            new Channel('admin.orders'),
        ];
    }

    public function broadcastAs(): string
    {
        return 'order.status.updated';
    }

    public function broadcastWith(): array
    {
        return [
            'order_id' => $this->order->id,
            'order_number' => $this->order->order_number,
            'previous_status' => $this->previousStatus,
            'new_status' => $this->newStatus,
            'updated_at' => now()->toISOString(),
        ];
    }
}

Das Frontend kann diese Events mit Laravel Echo empfangen und die Benutzeroberfläche entsprechend aktualisieren.

javascript
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT,
    forceTLS: true,
});

Echo.private(`orders.${userId}`)
    .listen('.order.status.updated', (event) => {
        console.log('Order status changed:', event);
        updateOrderStatus(event.order_id, event.new_status);
    });

Event Subscribers für komplexe Workflows

Event Subscribers ermöglichen es, mehrere Event-Handler in einer einzigen Klasse zu gruppieren. Dies ist nützlich für domänenspezifische Logik, die auf verschiedene Events reagieren muss.

php
<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use App\Events\OrderShipped;
use App\Events\OrderDelivered;
use App\Events\OrderCancelled;
use App\Services\NotificationService;
use Illuminate\Events\Dispatcher;

class OrderEventSubscriber
{
    public function __construct(
        private NotificationService $notifications
    ) {}

    public function handleOrderPlaced(OrderPlaced $event): void
    {
        $this->notifications->sendOrderConfirmation($event->order);
    }

    public function handleOrderShipped(OrderShipped $event): void
    {
        $this->notifications->sendShippingNotification(
            $event->order,
            $event->trackingNumber
        );
    }

    public function handleOrderDelivered(OrderDelivered $event): void
    {
        $this->notifications->sendDeliveryConfirmation($event->order);
        $this->notifications->requestReview($event->order);
    }

    public function handleOrderCancelled(OrderCancelled $event): void
    {
        $this->notifications->sendCancellationNotification(
            $event->order,
            $event->reason
        );
    }

    public function subscribe(Dispatcher $events): array
    {
        return [
            OrderPlaced::class => 'handleOrderPlaced',
            OrderShipped::class => 'handleOrderShipped',
            OrderDelivered::class => 'handleOrderDelivered',
            OrderCancelled::class => 'handleOrderCancelled',
        ];
    }
}

Der Subscriber wird im EventServiceProvider registriert und gruppiert alle zusammengehörigen Handler logisch.

php
protected $subscribe = [
    OrderEventSubscriber::class,
    PaymentEventSubscriber::class,
];

Bereit für deine Laravel-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

Interview-Fragen zu Laravel Events

Frage: Was ist der Unterschied zwischen Events und Observers in Laravel?

Events sind allgemeine Nachrichten, die überall in der Anwendung ausgelöst werden können und von beliebigen Listeners verarbeitet werden. Observers sind speziell für Eloquent-Models konzipiert und reagieren automatisch auf CRUD-Operationen. Events bieten mehr Flexibilität, während Observers für Model-spezifische Logik optimiert sind.

Frage: Wie verhindert man, dass ein Listener die Event-Propagation stoppt?

Wenn ein Listener false zurückgibt, werden nachfolgende Listener nicht mehr ausgeführt. Um dies zu vermeiden, sollten Listener entweder void oder einen anderen Wert zurückgeben. Die Reihenfolge der Listener im Array bestimmt die Ausführungsreihenfolge.

Frage: Wann sollte ShouldBeUnique bei Queued Listeners verwendet werden?

ShouldBeUnique verhindert, dass derselbe Job mehrfach in der Queue landet. Dies ist wichtig für idempotente Operationen wie E-Mail-Versand, bei denen Duplikate vermieden werden müssen.

php
class SendWelcomeEmail implements ShouldQueue, ShouldBeUnique
{
    public function uniqueId(): string
    {
        return $this->user->id;
    }
}

Frage: Wie testet man Event-basierte Logik?

Laravel bietet Event::fake() für isolierte Tests. Dies verhindert das tatsächliche Dispatchen von Events und ermöglicht Assertions.

php
public function test_order_placement_dispatches_event(): void
{
    Event::fake([OrderPlaced::class]);

    $order = Order::factory()->create();

    Event::assertDispatched(OrderPlaced::class, function ($event) use ($order) {
        return $event->order->id === $order->id;
    });
}

Fazit

Laravel Events und Listeners bilden ein leistungsstarkes System für entkoppelte, wartbare Anwendungsarchitekturen. Die Kombination aus synchronen Events, Queued Listeners und Broadcasting ermöglicht sowohl einfache Benachrichtigungen als auch komplexe Event-Driven Architectures. Model Observers vereinfachen die Reaktion auf Datenbankänderungen, während Event Subscribers zusammengehörige Handler gruppieren. Für technische Interviews ist ein tiefes Verständnis dieser Konzepte essentiell, da Event-Driven Architecture in modernen Laravel-Anwendungen zum Standard gehört.

Tägliche Challenge

Findest du den Bug in Laravel?

Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Anthony Fillion-Maillet

Geschrieben von

Anthony Fillion-Maillet

Gründer von SharpSkill

Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.

Aktualisiert am 20. August 2026

Tags

#laravel
#events
#listeners
#php
#event-driven

Teilen

Verwandte Artikel