


Implementierung ereignisgesteuerter Architekturen in PHP: Ein tiefer Einblick in Event Sourcing und CQRS
Sep 22, 2024 am 06:20 AMEvent-Driven Architecture (EDA) konzentriert sich darauf, Systeme zu entkoppeln und sie durch die Reaktion auf Ereignisse flexibler, skalierbarer und wartbarer zu machen. In PHP sind zwei wichtige Muster, die in EDA häufig verwendet werden, Event Sourcing und Command Query Responsibility Segregation (CQRS). Hier finden Sie eine Schritt-für-Schritt-Anleitung zur Implementierung mit PHP sowie ein praktisches Beispiel.
Konzeptübersicht
1. Event-Sourcing:
- Anstatt nur den Endzustand der Anwendung in der Datenbank zu speichern, wird jede Änderung (Ereignis) am Anwendungsstatus gespeichert.
- Beispiel: Wenn Sie über ein Bestellsystem verfügen, speichern Sie nicht nur den neuesten Bestellstatus, sondern jede Aktion in der Bestellung, wie „Bestellung erstellt“, „Artikel hinzugefügt“, „Bestellung bezahlt“ usw.
2. CQRS:
- CQRS trennt Lesen (Abfrage) und Schreiben (Befehl) Vorgänge. Die beiden Modelle können sich getrennt weiterentwickeln, wobei sich das Schreibmodell auf Geschäftslogik und Validierung konzentriert und das Lesemodell auf die Datendarstellung.
- Beispiel: Bei einem komplexen System wie einer E-Commerce-Website könnte die Logik zum Aufgeben einer Bestellung (Schreiben) vom Abrufen der Bestelldetails (Lesen) getrennt werden.
Architekturfluss
-
Befehl:
- Ein Befehl ist eine Aktion, die eine Statusänderung anfordert (z. B. „PlaceOrder“, „AddItemToOrder“).
- Der Befehl wird von einem Befehlshandler verarbeitet, der Geschäftslogik ausführt und Ereignisse ausgibt.
-
Ereignis:
- Nachdem ein Befehl verarbeitet wurde, wird ein Ereignis (z. B. „OrderPlaced“, „ItemAdded“) ausgelöst, das angibt, dass etwas Wichtiges passiert ist.
- Ereignisse sind unveränderlich und lösen Aktionen in anderen Teilen des Systems aus, beispielsweise die Aktualisierung von Lesemodellen oder die Benachrichtigung externer Systeme.
-
Modell lesen:
- Das Lesemodell wird durch die Reaktion auf Ereignisse aktuell gehalten. Es ist für Lesevorgänge optimiert und verfügt möglicherweise über ein anderes Schema als das Schreibmodell.
Schritt-für-Schritt-Beispiel: Ein Bestellsystem
Schritt 1: Projekt einrichten
Erstellen Sie eine Verzeichnisstruktur:
event-driven-php/ ├── src/ │ ├── Commands/ │ ├── Events/ │ ├── Handlers/ │ ├── Models/ │ └── ReadModels/ ├── tests/ └── vendor/
Abhängigkeiten installieren (z. B. Symfony/Event-Dispatcher):
composer require symfony/event-dispatcher
Schritt 2: Befehle definieren
Befehle stellen Aktionen dar, die den Zustand ändern. Beispiel: PlaceOrderCommand.php.
// src/Commands/PlaceOrderCommand.php class PlaceOrderCommand { public string $orderId; public string $customerId; public function __construct(string $orderId, string $customerId) { $this->orderId = $orderId; $this->customerId = $customerId; } }
Schritt 3: Ereignisse erstellen
Ereignisse beschreiben, was im System passiert ist. Beispiel: OrderPlacedEvent.php.
// src/Events/OrderPlacedEvent.php class OrderPlacedEvent { public string $orderId; public string $customerId; public function __construct(string $orderId, string $customerId) { $this->orderId = $orderId; $this->customerId = $customerId; } }
Schritt 4: Befehlshandler
Befehlshandler führen die eigentliche Geschäftslogik aus und lösen Ereignisse aus. Beispiel: PlaceOrderHandler.php.
// src/Handlers/PlaceOrderHandler.php use Symfony\Component\EventDispatcher\EventDispatcher; class PlaceOrderHandler { private EventDispatcher $eventDispatcher; public function __construct(EventDispatcher $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } public function handle(PlaceOrderCommand $command) { // Business logic (e.g., check stock, validate order) // Emit the event $event = new OrderPlacedEvent($command->orderId, $command->customerId); $this->eventDispatcher->dispatch($event, 'order.placed'); } }
Schritt 5: Ereignishandler (Projizieren von Daten zum Lesen von Modellen)
Ein Event-Handler wartet auf bestimmte Ereignisse und aktualisiert das Lesemodell. Beispiel: OrderProjection.php.
// src/ReadModels/OrderProjection.php class OrderProjection { private array $orders = []; public function onOrderPlaced(OrderPlacedEvent $event) { // Save or update read model with necessary data $this->orders[$event->orderId] = [ 'orderId' => $event->orderId, 'customerId' => $event->customerId, 'status' => 'placed' ]; } public function getOrder(string $orderId) { return $this->orders[$orderId] ?? null; } }
Schritt 6: Zusammenbau
use Symfony\Component\EventDispatcher\EventDispatcher; // Bootstrapping the system $dispatcher = new EventDispatcher(); $orderProjection = new OrderProjection(); // Register event listeners $dispatcher->addListener('order.placed', [$orderProjection, 'onOrderPlaced']); // Create the command and command handler $command = new PlaceOrderCommand('123', 'cust_001'); $handler = new PlaceOrderHandler($dispatcher); // Handle the command (Place the order) $handler->handle($command); // Query the read model for the order $order = $orderProjection->getOrder('123'); print_r($order);
Ausgabe:
Array ( [orderId] => 123 [customerId] => cust_001 [status] => placed )
Schritt 7: Event Store (optional)
Für eine vollständige Ereignisbeschaffung würden Sie auch einen Ereignisspeicher implementieren, um Ereignisse in einer Datenbank beizubehalten.
class EventStore { private array $storedEvents = []; public function append(Event $event) { $this->storedEvents[] = $event; } public function getEventsForAggregate(string $aggregateId): array { return array_filter($this->storedEvents, function($event) use ($aggregateId) { return $event->aggregateId === $aggregateId; }); } }
Teilweise Aufschlüsselung
- Befehlserstellung: Stellt die Absicht des Benutzers dar, etwas zu ändern.
- Befehlsverarbeitung: Geschäftslogik, die Befehle verarbeitet und Ereignisse auslöst.
- Ereignisemission: Ereignisse, die ausgelöst werden, nachdem Befehle erfolgreich verarbeitet wurden.
- Ereignisbehandlung: Projiziert die Ereignisdaten in Lesemodelle für optimierte Abfragen.
- CQRS-Trennung: Das Befehlsmodell konzentriert sich auf die Domänenlogik, während das Abfragemodell für schnelle Suchvorgänge optimiert ist.
- Ereignisspeicher: Behalten Sie optional Ereignisse bei, um den Status bei Bedarf wiederzugeben.
Abschluss
Dieses Beispiel zeigt eine einfache Anwendung von CQRS und Event Sourcing in PHP. Mit diesen Mustern können Sie Systeme erstellen, die gut skalierbar und wartbar sind und gleichzeitig eine leistungsstarke Überprüfbarkeit und flexible Lese-/Schreibverarbeitung bieten. Die Architektur kann mit zusätzlichen Projektionen, komplexerer Ereignisbehandlung und externen Integrationen wie Messaging-Warteschlangen oder Benachrichtigungen von Drittanbietern wachsen.
Das obige ist der detaillierte Inhalt vonImplementierung ereignisgesteuerter Architekturen in PHP: Ein tiefer Einblick in Event Sourcing und CQRS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heißer Artikel

Hot-Tools-Tags

Heißer Artikel

Heiße Artikel -Tags

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

11 beste PHP -URL -Shortener -Skripte (kostenlos und Premium)

Arbeiten mit Flash -Sitzungsdaten in Laravel

Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests

Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs

Erstellen Sie eine React -App mit einem Laravel -Back -Ende: Teil 2, reagieren

12 Beste PHP -Chat -Skripte auf Codecanyon
