Maison développement back-end tutoriel php Implémentation d'architectures basées sur les événements en PHP : une plongée approfondie dans le sourcing d'événements et le CQRS

Implémentation d'architectures basées sur les événements en PHP : une plongée approfondie dans le sourcing d'événements et le CQRS

Sep 22, 2024 am 06:20 AM

Implementing Event-Driven Architectures in PHP: A Deep Dive into Event Sourcing and CQRS

L'architecture pilotée par les événements (EDA) se concentre sur le découplage des systèmes et sur leur capacité à les rendre plus flexibles, évolutifs et maintenables en répondant aux événements. En PHP, deux modèles importants qui sont souvent utilisés dans EDA sont Event Sourcing et Command Query Responsibility Segregation (CQRS). Voici un guide étape par étape pour les implémenter à l’aide de PHP, ainsi qu’un exemple pratique.

Aperçu des concepts

1. Sourcing d'événements :

  • Au lieu de conserver uniquement l'état final de l'application dans la base de données, chaque modification (événement) de l'état de l'application est stockée.
  • Exemple : Si vous disposez d'un système de commande, au lieu de stocker uniquement le dernier statut de la commande, vous stockez chaque action sur la commande comme "Commande créée", "Article ajouté", "Commande payée", etc.

2. CQRS :

  • CQRS sépare les opérations lecture (requête) et écriture (commande). Les deux modèles peuvent évoluer séparément, le modèle d'écriture se concentrant sur la logique métier et la validation, et le modèle de lecture sur la représentation des données.
  • Exemple : Pour un système complexe comme un site de commerce électronique, la logique de passer une commande (écrire) pourrait être séparée de la récupération des détails de la commande (lire).

Flux architectural

  1. Commande :

    • Une commande est une action qui demande un changement d'état (par exemple, "PlaceOrder", "AddItemToOrder").
    • La commande est gérée par un Gestionnaire de commandes qui exécute la logique métier et émet des événements.
  2. Événement :

    • Une fois qu'une commande est traitée, un événement (par exemple, "OrderPlaced", "ItemAdded") est déclenché, indiquant que quelque chose d'important s'est produit.
    • Les événements sont immuables et déclenchent des actions dans d'autres parties du système, telles que la mise à jour des modèles de lecture ou la notification de systèmes externes.
  3. Lire le modèle :

    • Le modèle de lecture est tenu à jour en réagissant aux événements. Il est optimisé pour les opérations de lecture et peut avoir un schéma différent de celui du modèle d'écriture.

Exemple étape par étape : un système de commande

Étape 1 : Configuration du projet

Créez une structure de répertoires :

event-driven-php/
    ├── src/
    │   ├── Commands/
    │   ├── Events/
    │   ├── Handlers/
    │   ├── Models/
    │   └── ReadModels/
    ├── tests/
    └── vendor/
Copier après la connexion

Installer les dépendances (par exemple, symfony/event-dispatcher) :

composer require symfony/event-dispatcher
Copier après la connexion

Étape 2 : définir les commandes

Les commandes représentent des actions qui changent l'état. Exemple : 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;
    }
}
Copier après la connexion

Étape 3 : Créer des événements

Les événements décrivent ce qui s'est passé dans le système. Exemple : 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;
    }
}
Copier après la connexion

Étape 4 : Gestionnaires de commandes

Les gestionnaires de commandes exécutent la logique métier réelle et déclenchent des événements. Exemple : 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');
    }
}
Copier après la connexion

Étape 5 : Gestionnaires d'événements (projection de données pour lire des modèles)

Un gestionnaire d'événements écoute des événements spécifiques et met à jour le modèle de lecture. Exemple : 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;
    }
}
Copier après la connexion

Étape 6 : L'assembler

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);
Copier après la connexion

Sortie :

Array
(
    [orderId] => 123
    [customerId] => cust_001
    [status] => placed
)
Copier après la connexion

Étape 7 : Magasin d'événements (facultatif)

Pour un sourcing complet d'événements, vous devez également implémenter un magasin d'événements pour conserver les événements dans une base de données.

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;
        });
    }
}
Copier après la connexion

Répartition pièce par pièce

  1. Création de commande : représente l'intention de l'utilisateur de modifier quelque chose.
  2. Gestion des commandes : logique métier qui traite les commandes et déclenche des événements.
  3. Émission d'événements : les événements déclenchés après la gestion réussie des commandes.
  4. Gestion des événements : projette les données d'événement dans des modèles de lecture pour des requêtes optimisées.
  5. Séparation CQRS : le modèle de commande se concentre sur la logique de domaine, tandis que le modèle de requête est optimisé pour des recherches rapides.
  6. Event Store : éventuellement, conservez les événements pour rejouer l'état en cas de besoin.

Conclusion

Cet exemple démontre une application simple de CQRS et de Event Sourcing en PHP. Avec ces modèles, vous pouvez créer des systèmes bien évolutifs et maintenables, tout en offrant une auditabilité puissante et une gestion flexible de la lecture/écriture. L'architecture peut évoluer avec des projections supplémentaires, une gestion des événements plus complexe et des intégrations externes telles que des files d'attente de messagerie ou des notifications tierces.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

11 meilleurs scripts de raccourcissement d'URL PHP (gratuit et premium) 11 meilleurs scripts de raccourcissement d'URL PHP (gratuit et premium) Mar 03, 2025 am 10:49 AM

11 meilleurs scripts de raccourcissement d'URL PHP (gratuit et premium)

Introduction à l'API Instagram Introduction à l'API Instagram Mar 02, 2025 am 09:32 AM

Introduction à l'API Instagram

Travailler avec les données de session Flash dans Laravel Travailler avec les données de session Flash dans Laravel Mar 12, 2025 pm 05:08 PM

Travailler avec les données de session Flash dans Laravel

Construisez une application React avec un Laravel Back End: Partie 2, React Construisez une application React avec un Laravel Back End: Partie 2, React Mar 04, 2025 am 09:33 AM

Construisez une application React avec un Laravel Back End: Partie 2, React

Misque de réponse HTTP simplifié dans les tests Laravel Misque de réponse HTTP simplifié dans les tests Laravel Mar 12, 2025 pm 05:09 PM

Misque de réponse HTTP simplifié dans les tests Laravel

Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Mar 14, 2025 am 11:42 AM

Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST

12 meilleurs scripts de chat PHP sur Codecanyon 12 meilleurs scripts de chat PHP sur Codecanyon Mar 13, 2025 pm 12:08 PM

12 meilleurs scripts de chat PHP sur Codecanyon

Annonce de l'enquête sur la situation en 2025 PHP Annonce de l'enquête sur la situation en 2025 PHP Mar 03, 2025 pm 04:20 PM

Annonce de l'enquête sur la situation en 2025 PHP

See all articles