Events and Listeners
Laravel events provide a simple observer pattern implementation, allowing you to subscribe and listen for various events in your application. When an event is dispatched, all of its registered listeners are called automatically.
Events are a great way to decouple your application. Instead of calling multiple classes from one place, you dispatch an event and let interested listeners handle the rest.
Creating Events
An event class is a simple data container that holds the information related to the event. You can generate one using artisan.
php artisan make:event OrderPlaced
Inside the event class, you define the properties that carry the event data. For example, an OrderPlaced event might hold the order and user instances.
namespace App\Events;
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrderPlaced
{
use Dispatchable, SerializesModels;
public $order;
public function __construct(Order $order)
{
$this->order = $order;
}
}
The SerializesModels trait ensures that the event data is properly serialized when using queued listeners.
Creating Listeners
A listener is a class that responds to an event. Each listener has a handle method that receives the event instance.
php artisan make:listener SendOrderConfirmation
The listener receives the event through its handle method and can perform any logic in response.
namespace App\Listeners;
use App\Events\OrderPlaced;
use App\Mail\OrderConfirmationMail;
use Illuminate\Support\Facades\Mail;
class SendOrderConfirmation
{
public function handle(OrderPlaced $event)
{
Mail::to($event->order->user->email)
->send(new OrderConfirmationMail($event->order));
}
}
Listeners are kept small and focused. Each one handles a single responsibility, making your code easy to test and maintain.
Registering Events
The EventServiceProvider contains an $listen property that maps events to their listeners. This is where you define the relationships between events and the classes that respond to them.
namespace App\Providers;
use App\Events\OrderPlaced;
use App\Listeners\SendOrderConfirmation;
use App\Listeners\UpdateInventory;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
],
];
public function boot()
{
$this->boot();
}
}
You can register multiple listeners for a single event. When the event is dispatched, every listener in the array will be executed.
Dispatching Events
Dispatching an event is as simple as calling the dispatch method on the event class. You can dispatch events from controllers, models, or anywhere in your application.
use App\Events\OrderPlaced;
OrderPlaced::dispatch($order);
You can also use the event() helper function or the Event facade to dispatch events.
event(new OrderPlaced($order));
event('order.placed', [$order]);
Events can be dispatched synchronously or queued depending on your needs. By default, listeners are executed synchronously.
Queued Listeners
If a listener performs slow operations like sending emails or processing files, you can queue it. Simply implement the ShouldQueue interface on the listener class.
namespace App\Listeners;
use App\Events\OrderPlaced;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendOrderConfirmation implements ShouldQueue
{
public $queue = 'emails';
public function handle(OrderPlaced $event)
{
// this runs in the background via queue worker
}
}
Queued listeners run in the background, keeping your application responsive. You can set queue names, connection settings, and retry logic on the listener.
Event Subscribers
Event subscribers allow you to listen for multiple events from within a single class. The subscriber class defines a subscribe method that registers listeners.
namespace App\Listeners;
class UserEventSubscriber
{
public function handleUserLogin($event)
{
// respond to login
}
public function handleUserLogout($event)
{
// respond to logout
}
public function subscribe($events)
{
$events->listen(
'Illuminate\Auth\Events\Login',
[self::class, 'handleUserLogin']
);
$events->listen(
'Illuminate\Auth\Events\Logout',
[self::class, 'handleUserLogout']
);
}
}
Register the subscriber in the EventServiceProvider by adding it to the $subscribe property. This keeps all related event handling in one place.