Listeners/Escuchadores y Eventos en Laravel

Video thumbnail

Índice de contenido

Los listeners y eventos en Laravel son una de esas herramientas que, cuando las entiendes bien, te cambian por completo la forma de estructurar una aplicación. No solo hacen el código más limpio, sino que te permiten desacoplar lógica, reutilizar comportamientos y evitar controladores inflados de responsabilidades.

Los Eventos de Laravel proporcionan una implementación sencilla del patrón de diseño Observer, permitiéndote suscribirte y escuchar diversas acciones que ocurren en tu aplicación. Es la herramienta definitiva para el desacoplamiento de lógica, permitiendo que una acción principal (como un registro de usuario) dispare múltiples tareas secundarias (como enviar un correo, crear un perfil o notificar a Slack) sin saturar el controlador original.

En este artículo voy a explicarte qué son, cómo funcionan realmente, qué cambió a partir de Laravel 11, y lo más importante: cuándo tiene sentido usarlos, con ejemplos prácticos y un caso real que me encontré trabajando con autenticación y sesiones.

¿Qué son los eventos y listeners en Laravel?

Laravel implementa de forma nativa el patrón observador, lo que significa que una parte del sistema puede “avisar” que algo ocurrió, y otras partes pueden reaccionar a eso sin estar directamente acopladas.

Evento: qué representa y cuándo se dispara

Un evento es simplemente una notificación de que algo ocurrió en la aplicación.
Ejemplos típicos:

  • Un usuario se registró
  • Un usuario inició sesión
  • Se creó un pedido
  • Se actualizó un modelo importante

El evento no contiene lógica, solo datos relacionados con lo que ocurrió.

Listener: qué hace y por qué es clave

Un listener (escuchador) es la clase que reacciona al evento y ejecuta una acción concreta:

  • Enviar un email
  • Mandar una notificación
  • Actualizar stock
  • Registrar información
  • Sincronizar datos

La clave es que el evento no sabe quién lo escucha, y el listener no necesita saber dónde se disparó el evento.

Patrón observador aplicado en Laravel

Gracias a este patrón:

  • El código queda desacoplado
  • Puedes añadir o quitar comportamientos sin tocar la lógica principal
  • Un mismo evento puede tener muchos listeners

Esto es exactamente lo que Laravel hace internamente con autenticación, registro, verificación de email, etc.

¿Para qué sirven los listeners de eventos en Laravel?

Los listeners sirven para sacar lógica secundaria fuera del flujo principal de la aplicación.

Desacoplar lógica de negocio

En lugar de hacer esto en un controlador:

 
// guardar usuario // enviar email // notificar admin // escribir en logs 

Puedes simplemente:

 
event(new UserRegistered($user));

Y dejar que cada listener haga su trabajo.

Ejecutar múltiples acciones a partir de un solo evento

Un evento puede disparar:

  • Un listener que envía un email
  • Otro que notifica al administrador
  • Otro que actualiza métricas

Todos independientes entre sí.

Casos típicos de uso

  • Emails de bienvenida
  • Notificaciones (Slack, SMS, push)
  • Logging
  • Procesos en segundo plano
  • Sincronización de datos
  • Automatizaciones internas

Cómo funcionan los eventos y listeners en Laravel (flujo completo)

En el ecosistema de Laravel, el flujo de trabajo se divide en dos componentes críticos:

  • Event (El Evento): Es una clase que actúa como un "contenedor" de datos. Se dispara cuando algo sucede en la aplicación.
  • Listener (El Escuchador): Es la clase que contiene la lógica que debe ejecutarse cuando el evento es disparado.

Beneficios de implementar Eventos:

  • Modularidad: Separa las responsabilidades de tu código siguiendo los principios SOLID.
  • Escalabilidad: Añade nuevas funcionalidades tras un proceso existente sin tocar el código original.
  • Asincronía: Gracias a la integración nativa con Laravel Queues, puedes ejecutar listeners en segundo plano para mejorar el tiempo de respuesta del usuario.

En la práctica:

1. Disparar un evento

Cuando ocurre algo importante:

 
event(new UserRegistered($user));
// o UserRegistered::dispatch($user);

2. Escuchar el evento

Laravel busca automáticamente los listeners asociados a ese evento.

3. Ejecutar el listener

Se ejecuta el método:

 
handle() 
// o __invoke()

Del listener correspondiente.

Tipos de Eventos en Laravel

1. Eventos del Sistema (Internos)

Laravel dispara eventos automáticamente durante el ciclo de vida de la aplicación. Algunos de los más útiles incluyen:

  • Auth Events: Registered, Login, Logout, Failed.
  • Database Events: QueryExecuted.
  • Eloquent Models: creating, updated, deleting (también conocidos como Model Observers).

2. Eventos Personalizados

Puedes generar tus propios eventos para procesos de negocio específicos con el comando Artisan:

$ php artisan make:event OrderProcessed

Cambios importantes a partir de Laravel 11: autodetección de listeners

Aquí hay un punto clave que mucha gente pasa por alto.

Cómo funcionaba antes (EventServiceProvider)

Antes de Laravel 11, tenías que registrar manualmente todo en EventServiceProvider:

 
protected $listen = [
    UserRegistered::class => [
        SendWelcomeEmail::class,
    ],
];

Event Discovery: Cómo funciona ahora la autodetección

Desde Laravel 11, esto ya no es obligatorio.

Laravel escanea automáticamente el directorio app/Listeners y:

  • Detecta métodos handle()
  • O métodos __invoke()
  • Usa el type-hint del evento para asociarlos

En la mayoría de los casos no necesitas tocar el EventServiceProvider.

Qué métodos detecta Laravel

  • public function handle(Event $event)
  • public function __invoke(Event $event)

Simple, limpio y sin configuración extra.

Crear un evento y su listener en Laravel (ejemplo básico)

Definición del evento

 
namespace App\Events;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class UserRegistered
{
    use Dispatchable, SerializesModels;
    public function __construct(
        public readonly User $user
    ) {}
}

El evento solo transporta datos.

Creación del listener

 
php artisan make:listener SendWelcomeEmail --event=UserRegistered
 
namespace App\Listeners;
use App\Events\UserRegistered;
class SendWelcomeEmail
{
    public function handle(UserRegistered $event): void
    {
        // Mail::to($event->user)->send(...)
    }
}

Laravel detecta esto automáticamente.

Despachando el evento

 
event(new UserRegistered($user));

O:

 
UserRegistered::dispatch($user);

Caso práctico real: usar un listener en el login de Laravel

Supongamos el siguiente escenario:

  • Un usuario agrega productos al carrito antes de autenticarse
  • Esos datos se guardan en base de datos
  • Al hacer login, necesitaba replicar el carrito desde BD a la sesión

Podría haber:

  • Sobrescrito el método de login
  • Metido lógica en el controlador
  • Tocado Fortify

Pero preferí algo mucho más modular.

El problema: sincronizar datos tras la autenticación

Laravel ya dispara internamente el evento:

 
Illuminate\Auth\Events\Login

Así que no tenía sentido reinventar nada.

Por qué usar un listener en lugar de sobrescribir el login

  • No acoplo lógica de negocio al proceso de autenticación
  • Puedo cambiar o eliminar el comportamiento sin tocar el login
  • El código queda reutilizable y claro

Escuchando el evento Login de Laravel

 
php artisan make:listener LoginSuccessful --event=Illuminate\Auth\Events\Login
 
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use App\Models\ShoppingCart;
use Illuminate\Support\Arr;
class LoginSuccessful
{
    public function handle(Login $event): void
    {
        $cartDB = ShoppingCart::where('user_id', auth()->id())->get();
        $cartSession = session('cart', []);
        foreach ($cartDB as $c) {
            if (Arr::exists($cartSession, $c->post->id)) {
                $cartSession[$c->post->id][1] = $c->count;
            } else {
                $cartSession[$c->post->id] = [$c->post, $c->count];
            }
        }
        session(['cart' => $cartSession]);
    }
}

Cada vez que el usuario inicia sesión, el carrito queda sincronizado automáticamente.

Sin tocar el login. Sin hacks.

Listener vs callback directo: cuándo usar cada uno

Laravel también permite escuchar eventos directamente con un callback.

Listener dedicado

✔ Más limpio
✔ Mejor escalabilidad
✔ Ideal para lógica reutilizable

Callback en AppServiceProvider

✔ Más rápido para scripts simples
✔ Menos archivos

 
Event::listen(Login::class, function () {
    // lógica rápida
});

Para cosas pequeñas está bien, pero cuando crece, el listener dedicado gana.

Listeners en cola (Queued Listeners) en Laravel

Si el listener hace algo lento (emails, HTTP, integraciones), no debería ejecutarse en la request principal.

Cuándo usar listeners en cola

  • Envío de correos
  • Notificaciones externas
  • Procesos pesados

Implementando ShouldQueue

 
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class SendWelcomeEmail implements ShouldQueue
{
    use InteractsWithQueue;
    public function handle(UserRegistered $event): void
    {
        //
    }
}

Esto mejora rendimiento y experiencia de usuario.

Eventos, colas y transacciones de base de datos

Un error común: usar listeners en cola antes de que una transacción haga commit.

El problema

El listener puede ejecutarse cuando los datos aún no existen en BD.

Solución: ShouldHandleEventsAfterCommit

 
use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit;
class SendWelcomeEmail implements ShouldQueue, ShouldHandleEventsAfterCommit
{
    //
}

Así te aseguras consistencia total.

Errores comunes al usar eventos y listeners en Laravel

  • Meter demasiada lógica dentro del listener
  • Usar eventos para cosas triviales
  • No considerar colas
  • Ignorar transacciones
  • Crear eventos innecesarios

Los eventos son una herramienta, no una religión.

Preguntas frecuentes sobre eventos y listeners en Laravel

¿Es obligatorio usar EventServiceProvider en Laravel 11?
No, salvo configuraciones avanzadas.

¿Puedo usar eventos sin colas?
Sí, son síncronos por defecto.

¿Listeners o lógica directa en el controlador?
Si la lógica se repite o crece, listener.

¿Qué evento se dispara al hacer login?
Illuminate\Auth\Events\Login

Conclusión

Los listeners y eventos en Laravel son una de las mejores formas de mantener una arquitectura limpia, escalable y fácil de mantener. A partir de Laravel 11, su uso es aún más simple gracias a la autodetección, y cuando los combinas con colas y buenas prácticas, se convierten en una herramienta extremadamente potente.

En mi experiencia, usarlos para resolver problemas reales (como sincronizar datos tras el login) marca la diferencia entre una solución rápida y una solución bien diseñada.

Aprende a usar los Eventos y Listeners en Laravel. Descubre cómo aplicar el patrón Observer para desacoplar lógica, mejorar la escalabilidad y crear aplicaciones PHP modulares y eficientes.

Acepto recibir anuncios de interes sobre este Blog.

Andrés Cruz

EN In english