Responding to Application Events
When you need to run code in response to application events—sending welcome emails after user registration, invalidating caches when data changes, logging payment activity—register event listeners that fire when those events occur.
Listening for Events
Section titled “Listening for Events”Register a listener with on() and trigger it with emit():
app()->on('user.created', fn($payload) => sendWelcomeEmail($payload['user']));
// Later, when a user is createdapp()->emit('user.created', ['user' => $user]);The listener runs whenever you emit that event.
Using Class-Based Listeners
Section titled “Using Class-Based Listeners”Listeners can be classes that resolve through the container:
class SendWelcomeEmail{ public function __construct(private EmailService $emails) {}
public function __invoke(array $payload): void { $this->emails->send($payload['user']['email'], 'Welcome!'); }}
app()->on('user.created', SendWelcomeEmail::class);Dependencies are automatically injected when the listener runs.
Running Multiple Actions per Event
Section titled “Running Multiple Actions per Event”You can attach multiple listeners to the same event:
app() ->on('user.created', SendWelcomeEmail::class) ->on('user.created', UpdateAnalytics::class) ->on('user.created', LogUserCreation::class);Listeners execute in registration order.
Listening to Event Patterns
Section titled “Listening to Event Patterns”Use wildcards to match multiple events:
// Match user.created, user.updated, user.deleted, etc.app()->on('user.*', fn($payload) => logUserEvent($payload));
// Match every eventapp()->on('*', fn($payload) => logAllEvents($payload));Invalidating Caches on Data Changes
Section titled “Invalidating Caches on Data Changes”Events are useful for cache invalidation without coupling your business logic to caching:
app()->on('product.updated', function($payload) use ($cache) { $cache->forget('product:' . $payload['id']);});
// Elsewhere, after updating a productapp()->emit('product.updated', ['id' => $product->id]);Sending Notifications
Section titled “Sending Notifications”Run multiple side effects when something important happens:
app()->on('order.completed', function($payload) { $order = $payload['order']; sendCustomerEmail($order); notifyWarehouse($order); updateInventory($order);});Logging Activity
Section titled “Logging Activity”Track important events across a domain:
app()->on('payment.*', function($payload) use ($logger) { $logger->info('Payment event', $payload);});This catches payment.succeeded, payment.failed, payment.refunded, and any other payment events you emit.
Checking for Listeners
Section titled “Checking for Listeners”Skip emitting events if nothing is listening:
if (app()->hasListeners('user.created')) { app()->emit('user.created', ['user' => $user]);}Naming Events
Section titled “Naming Events”Use dot notation to namespace related events:
user.created,user.updated,user.deletedorder.completed,order.refundedpayment.succeeded,payment.failed
This makes wildcard matching intuitive and keeps your events organized.