Skip to main content

Qué son los eventos

El sistema de eventos de Laravel es una implementación sencilla del patrón observer. Al despachar los sucesos (eventos) que ocurren en la aplicación y definir listeners que reaccionan a ellos, se reduce al mínimo la dependencia entre componentes. Por ejemplo, al despachar el evento «pedido confirmado» pueden ejecutarse de forma independiente varios listeners: «enviar correo de confirmación», «descontar stock», «notificar a Slack», etc. El código de procesamiento del pedido no necesita saber absolutamente nada de la implementación del envío del correo ni de la notificación a Slack.
Las clases de evento se ubican en app/Events y las de listener en app/Listeners. Si esos directorios no existen, los comandos Artisan los crean automáticamente.

Generar eventos y listeners

Utiliza los comandos Artisan make:event y make:listener para generar el esqueleto.
Sin argumentos, los comandos te preguntan de forma interactiva.

Registro de eventos

Descubrimiento automático de eventos

Por defecto, Laravel escanea el directorio app/Listeners y registra los listeners automáticamente. Deduce la asociación con el evento inspeccionando el tipo del argumento del método handle o __invoke.
Usando tipos union de PHP puedes escuchar varios eventos en el mismo método.
Si tus listeners están en otro directorio, indícalo en bootstrap/app.php.
Puedes usar comodines para incluir varios directorios de una vez.
Puedes ver la lista de listeners registrados con este comando:
En producción, cachear el manifiesto de listeners mejora el rendimiento. Al desplegar ejecuta php artisan optimize o php artisan event:cache. Para borrar la caché usa php artisan event:clear.

Registro manual

También puedes registrar los listeners manualmente en el método boot de AppServiceProvider con el facade Event.
También puedes registrarlos como closure.

Definir el evento

Las clases de evento son contenedores de datos. No contienen lógica y guardan como propiedades la información asociada al evento.
El trait SerializesModels garantiza que los modelos Eloquent se manejen correctamente cuando los listeners encolados serialicen el evento.

Despachar eventos

Despacha eventos con el método estático dispatch o con el helper event().
También hay métodos para despachar de forma condicional.

Despachar tras una transacción de base de datos

Cuando quieras despachar el evento solo después de que la transacción se haya confirmado, implementa la interfaz ShouldDispatchAfterCommit en la clase del evento. Si la transacción falla, el evento se descarta.

Implementar el listener

El listener recibe el evento en su método handle. En el constructor, el contenedor de servicios inyecta automáticamente las dependencias.
Si el método handle devuelve false, se detiene la propagación del evento a los siguientes listeners.

Listeners encolados

Los procesos lentos, como el envío de correos o las peticiones HTTP, pueden ejecutarse de forma asíncrona con listeners encolados. Con solo implementar la interfaz ShouldQueue, el listener se encolará automáticamente al despachar el evento.
Antes de usar listeners encolados necesitas configurar la cola y arrancar el worker. Consulta la página de colas y jobs para más detalles.

Debounce de listeners de eventos

Cuando un mismo evento se dispara muchas veces en un corto intervalo, puede que solo quieras procesar el último. Añadiendo el atributo DebounceFor a un listener encolado, puedes agrupar los eventos que ocurran dentro de un periodo dado.
En este ejemplo, si eventos ProductUpdated para el mismo producto se disparan repetidamente dentro de 30 segundos, el listener queda en debounce y solo se procesa el último evento. Los eventos con un debounceId distinto se procesan de forma independiente. Para limitar cuánto tiempo pueden retrasar el listener los eventos que se disparan con frecuencia, indica maxWait.
Puedes cambiar el almacén de caché que se usa para seguir el debounce con el método debounceVia, que recibe el evento.
No puedes usar a la vez listeners con debounce y listeners únicos. No implementes ShouldBeUnique en un listener que usa el atributo DebounceFor. Cuando dispares eventos desde varios servidores web o contenedores, configura todos los servidores para que usen el mismo servidor de caché compartido.

Personalizar conexión, nombre de cola y retraso

Con atributos PHP puedes definir la conexión, la cola y el retraso.
También puedes calcular los valores dinámicamente mediante métodos.

Reintentos y timeout máximos

Con los atributos #[Tries] y #[Timeout] puedes controlar el comportamiento ante fallos.

Gestión de fallos

Si defines el método failed, puedes ejecutar código adicional cuando el listener agote los reintentos.

Suscriptores de eventos

Los suscriptores permiten agrupar varios handlers relacionados en una única clase.

Crear un suscriptor

En el método subscribe devuelves un array con la asignación entre eventos y handlers.

Registrar el suscriptor

Con el descubrimiento automático activado, los suscriptores cuyo subscribe devuelve un array se registran automáticamente. Para registrarlos manualmente utiliza Event::subscribe en el método boot de AppServiceProvider.

Ejemplo práctico: enviar un correo de bienvenida al registrarse un usuario

1

Crear la clase de evento

Edita app/Events/UserRegistered.php para añadir una propiedad con el usuario registrado.
2

Crear la clase de listener

Para enviar el correo de forma asíncrona en la cola, implementa ShouldQueue.
3

Despachar el evento desde el controlador

Llama a UserRegistered::dispatch() después de crear el usuario.
El RegisterController se limita a despachar el evento UserRegistered sin saber nada del envío del correo. Si en el futuro quisiéramos «enviar además una notificación a Slack al registrarse», no habría que tocar el controlador.
4

Arrancar el worker

Arranca el worker para procesar los listeners encolados.
Con el descubrimiento automático activado no hace falta registrar los listeners manualmente en AppServiceProvider. Se detectan automáticamente todos los que estén en app/Listeners.
Con php artisan event:list puedes revisar los eventos y listeners registrados. Revisa periódicamente que no haya listeners inesperados en la lista.
Última modificación el 21 de agosto de 2026