Laravel Tutorial · Beyond the Basics · Lesson 23 of 27
Events, Listeners and Notifications
Decouple your code with events and listeners, and send notifications to users over mail, database, SMS or Slack channels.
Events and listeners
When something happens ("an order was placed"), fire an event; any number of listeners react (send a receipt, update stock, notify the warehouse) without the order code knowing about them.
php artisan make:event OrderPlaced
php artisan make:listener SendOrderReceipt --event=OrderPlaced
Listeners are discovered automatically from type hints, or registered with Event::listen(...). A listener implementing ShouldQueue runs in the background. Eloquent fires model events (created, updated, deleted) you can observe too.
Notifications
A notification sends one message over several channels: mail, database (an in-app inbox), broadcast, SMS or Slack. Users get them with $user->notify(new OrderShipped($order)).
<?php
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Support\Facades\Event;
class OrderPlaced
{
use Dispatchable; // adds OrderPlaced::dispatch(...)
public function __construct(public string $orderId, public float $total) {}
}
class SendOrderReceipt
{
public function handle(OrderPlaced $event): void
{
echo " receipt emailed for {$event->orderId}\n";
}
}
class UpdateStock
{
public function handle(OrderPlaced $event): void
{
echo " stock reserved for {$event->orderId}\n";
}
}
Event::listen(OrderPlaced::class, SendOrderReceipt::class);
Event::listen(OrderPlaced::class, UpdateStock::class);
Event::listen(OrderPlaced::class, function (OrderPlaced $event) {
if ($event->total > 100) {
echo " big order alert: {$event->orderId}\n";
}
});
echo "placing A-100 (49.90):\n";
OrderPlaced::dispatch('A-100', 49.90);
echo "placing A-101 (250.00):\n";
event(new OrderPlaced('A-101', 250.00));
Event::fake([OrderPlaced::class]); // in tests: capture events instead of running listeners
OrderPlaced::dispatch('A-102', 10.00);
Event::assertDispatched(OrderPlaced::class, fn ($e) => $e->orderId === 'A-102');
echo "test assertion passed: OrderPlaced was dispatched for A-102\n";
Output
placing A-100 (49.90): receipt emailed for A-100 stock reserved for A-100 placing A-101 (250.00): receipt emailed for A-101 stock reserved for A-101 big order alert: A-101 test assertion passed: OrderPlaced was dispatched for A-102
Run this on your computer — see “Get Started” for setup.
Test yourself
What's the main benefit of events and listeners?
Faster SQLCode that triggers something doesn't need to know everything that reacts to itThey replace validationThey cache responses
Show answer
Answer: Code that triggers something doesn't need to know everything that reacts to it