Event Bus y el patrón Observer en PHP: implementación y ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Event Bus y el patrón Observer en PHP



En el desarrollo moderno de aplicaciones web en PHP, a menudo surge la necesidad de reaccionar de manera flexible a diversos eventos: enviar un correo electrónico después del registro, registrar las acciones del usuario, actualizar la caché al modificar datos. Para estos fines, el patrón Observer y su extensión — Event Bus (bus de eventos) — son ideales.



Patrón Observer: fundamentos



El patrón Observer (Observador) es un patrón de diseño de comportamiento que crea un mecanismo de suscripción que permite a unos objetos observar y reaccionar ante eventos que ocurren en otros objetos. Componentes principales:



  • Subject (Sujeto) — el objeto que genera eventos
  • Observer (Observador) — el objeto que reacciona a los eventos
  • Event (Evento) — la información sobre la acción ocurrida


Event Bus: evolución de Observer



Event Bus es un bus centralizado que gestiona todos los eventos en la aplicación. A diferencia del Observer clásico, donde la suscripción está rígidamente vinculada al sujeto, Event Bus proporciona:



  • Acoplamiento débil entre emisores y receptores
  • Posibilidad de añadir/eliminar manejadores durante la ejecución
  • Acceso global al bus desde cualquier parte de la aplicación
  • Pruebas y depuración simplificadas


Ejemplo de implementación de Event Bus en PHP



Crearemos una implementación simple pero funcional de Event Bus, compatible con PSR-14 (Event Dispatcher).



<?php// Interfaz de eventointerface EventInterface{    public function getName(): string;}

// Evento 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; }}

// Interfaz del manejadorinterface 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); } }}?>


Uso práctico



Ahora crearemos manejadores y demostraremos el funcionamiento del bus:



<?php// Manejador de envío de correo electrónicoclass SendWelcomeEmailHandler implements EventHandlerInterface{    public function handle(EventInterface $event): void    {        if (!$event instanceof UserRegisteredEvent) {            return;        }

echo "Enviando correo de bienvenida a {$event->getEmail()}"; // mail($event->getEmail(), '¡Bienvenido!', '...'); }}

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

Recommendations