CQRS und Event Sourcing in PHP: Architektur für komplexe Projekte

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum gewöhnliches CRUD bei wachsendem Projekt nicht mehr funktioniert

\n\n

Stellen Sie sich vor: Sie schreiben einen Online-Shop in PHP. Zuerst ist alles einfach – Produkt hinzugefügt, Preis geändert, gelöscht. Aber nach einem halben Jahr kommen neue Anforderungen hinzu: Audit aller Änderungen, Wiederherstellung von Daten zu einem bestimmten Datum, komplexe Rabattlogik. Gewöhnliches CRUD (Create, Read, Update, Delete) beginnt zu bröckeln. Die Datenbank wird zum Chaos, und jede neue Kundenanfrage erfordert das Umschreiben der Hälfte des Systems.

\n\n

Kommt Ihnen das bekannt vor? Dann werden Ihnen CQRS (Command Query Responsibility Segregation) und Event Sourcing sicher nützlich sein – zwei leistungsstarke Muster, die den Ansatz zur Entwicklung verändern. In diesem Artikel analysieren wir sie anhand realer PHP-Beispiele, damit Sie sie in Ihren Projekten anwenden können.

\n\n

Was sind CQRS und Event Sourcing in einfachen Worten

\n\n

CQRS: Trennung von Befehlen und Abfragen

\n\n

CQRS ist ein Architekturmuster, das Operationen in zwei Typen unterteilt: Befehle (ändern den Zustand) und Abfragen (lesen den Zustand). Im klassischen MVC arbeiten sowohl der Controller als auch das Modell mit denselben Entitäten. CQRS schlägt vor, diese Verantwortlichkeiten zu trennen.

\n\n

Stellen Sie sich eine Bibliothek vor: Es gibt einen separaten Tisch zum Ausleihen von Büchern (Befehle) und einen separaten Tisch zum Lesen (Abfragen). Niemand stört den anderen, und jeder ist für seine Aufgabe optimiert.

\n\n

Event Sourcing: Änderungsverlauf statt aktuellem Zustand

\n\n

Event Sourcing ist eine Methode der Datenspeicherung, bei der Sie nicht den aktuellen Zustand eines Objekts speichern, sondern die Abfolge aller Ereignisse, die zu diesem Zustand geführt haben. Anstelle einer einzelnen Zeile "Bestellung Nr. 123: Status = geliefert" speichern Sie: "Bestellung erstellt → Bezahlt → Versandt → Geliefert".

\n\n

Das ist wie eine Videoaufnahme anstelle eines Fotos: Sie können jederzeit zurückspulen und sehen, was zu einem bestimmten Zeitpunkt passiert ist.

\n\n

Wann sollte man CQRS und Event Sourcing in PHP einsetzen

\n\n

Diese Muster sind keine silberne Kugel. Für einen einfachen Blog sind sie überdimensioniert. Aber hier sind Szenarien, in denen sie unverzichtbar sind:

\n\n
    \n
  • Komplexe Domänenlogik (Finanzen, Buchung, Logistik)
  • \n
  • Audit-Anforderungen – Sie müssen wissen, wer wann Daten geändert hat
  • \n
  • Wiederherstellung des Zustands zu einem beliebigen Datum
  • \n
  • Mikroservice-Architektur – Ereignisse lassen sich leicht zwischen Diensten übertragen
  • \n
  • Hohe Leselast – Sie können ein separates, für Abfragen optimiertes Read-Modell erstellen
  • \n
\n\n

Wenn Ihr Projekt ein Online-Shop mit Tausenden von Bestellungen, ein CRM-System oder eine Bankanwendung ist – dann werden Ihnen CQRS und Event Sourcing sicher nützlich sein.

\n\n

Praktische Implementierung von CQRS in PHP

\n\n

Kommen wir zum Code. Wir implementieren ein einfaches Bestellverwaltungssystem. Beginnen wir mit CQRS.

\n\n

Schritt 1: Befehle und Abfragen definieren

\n\n

Ein Befehl ist ein DTO (Data Transfer Object), das alle Daten zur Ausführung einer Operation enthält. Ein Befehl gibt niemals Daten zurück – er ändert nur den Zustand.

\n\n
<?php\n// src/Application/Command/CreateOrderCommand.php\nnamespace App\\Application\\Command;\n\nclass CreateOrderCommand\n{\n    public function __construct(\n        public readonly string $orderId,\n        public readonly string $customerId,\n        public readonly array $items, // [['productId' => '...', 'quantity' => 2], ...]\n        public readonly \\DateTimeImmutable $createdAt\n    ) {}\n}\n
\n\n

Eine Abfrage ist ebenfalls ein DTO, jedoch zum Lesen. Sie kann Filter enthalten und Daten zurückgeben.

\n\n
<?php\n// src/Application/Query/GetOrderQuery.php\nnamespace App\\Application\\Query;\n\nclass GetOrderQuery\n{\n    public function __construct(\n        public readonly string $orderId\n    ) {}\n}\n
\n\n

Schritt 2: Befehlshandler erstellen

\n\n

Ein Befehlshandler ist ein Dienst, der die Geschäftslogik ausführt. Er nimmt einen Befehl entgegen und ändert den Zustand

Blogs

Buchempfehlungen