Event Bus et le pattern Observer en PHP : implémentation et exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Event Bus et le pattern Observer en PHP



Dans le développement moderne d'applications web en PHP, il est souvent nécessaire de réagir de manière flexible à divers événements : envoi d'email après une inscription, journalisation des actions des utilisateurs, mise à jour du cache lors de la modification de données. Pour ces objectifs, le pattern Observer et son extension — l'Event Bus (bus d'événements) — sont parfaitement adaptés.



Le pattern Observer : bases



Le pattern Observer (Observateur) est un modèle de conception comportemental qui crée un mécanisme d'abonnement permettant à certains objets de surveiller et de réagir aux événements se produisant dans d'autres objets. Composants principaux :



  • Subject (Sujet) — l'objet qui génère les événements
  • Observer (Observateur) — l'objet qui réagit aux événements
  • Event (Événement) — l'information sur l'action qui s'est produite


Event Bus : évolution de l'Observer



L'Event Bus est un bus centralisé qui gère tous les événements dans l'application. Contrairement à l'Observer classique où l'abonnement est strictement lié au sujet, l'Event Bus offre :



  • Un couplage faible entre les expéditeurs et les destinataires
  • La possibilité d'ajouter/supprimer des gestionnaires pendant l'exécution
  • Un accès global au bus depuis n'importe quelle partie de l'application
  • Des tests et un débogage simplifiés


Exemple d'implémentation d'un Event Bus en PHP



Créons une implémentation simple mais fonctionnelle d'un Event Bus, compatible avec PSR-14 (Event Dispatcher).



<?php// Interface d'événementinterface EventInterface{    public function getName(): string;}

// Événement de baseclass UserRegisteredEvent implements EventInterface{ public function __construct( private string $email, private string $username ) {}

public function getName(): string { return 'user.registered'; }

public function getEmail(): string { return $this->email; }

public function getUsername(): string { return $this->username; }}

// Interface du gestionnaireinterface EventHandlerInterface{ public function handle(EventInterface $event): void;}

// Event Busclass EventBus{ private array $listeners = [];

public function addListener(string $eventName, EventHandlerInterface $handler): void { $this->listeners[$eventName][] = $handler; }

public function removeListener(string $eventName, EventHandlerInterface $handler): void { if (!isset($this->listeners[$eventName])) { return; }

$this->listeners[$eventName] = array_filter( $this->listeners[$eventName], fn($h) => $h !== $handler ); }

public function dispatch(EventInterface $event): void { $eventName = $event->getName();

if (!isset($this->listeners[$eventName])) { return; }

foreach ($this->listeners[$eventName] as $handler) { $handler->handle($event); } }}?>


Utilisation pratique



Créons maintenant des gestionnaires et démontrons le fonctionnement du bus :



<?php// Gestionnaire d'envoi d'emailclass SendWelcomeEmailHandler implements EventHandlerInterface{    public function handle(EventInterface $event): void    {        if (!$event instanceof UserRegisteredEvent) {            return;        }

echo "Envoi de l'email de bienvenue à {$event->getEmail()}"; // mail($event->getEmail(), 'Bienvenue !', '...'); }}

// Gestionnaire de journalisationclass LogUserRegistrationHandler implements EventHandlerInterface{ public function handle(EventInterface $event): void { if (!$event instanceof UserRegisteredEvent) { return; }

Recommendations