Event Dispatcher
Listen for and dispatch events across your application.
The event dispatcher provides a simple pub/sub system. Components fire events when things happen; other components listen and react. Events are notifications-they inform you that something occurred but shouldn't be used to modify the core flow.
Listening for Events #
$events = app('events');
$events->listen('page.saved', function (array $page) {
// React to page being saved
$this->cache->flush('pages');
$this->searchIndex->update($page);
});
Listeners receive whatever payload was passed when the event was dispatched.
Dispatching Events #
$events->dispatch('page.saved', [
'id' => $page->id,
'slug' => $page->slug,
'title' => $page->title,
]);
The second argument can be any value-typically an array with relevant data.
Multiple Listeners #
You can register multiple listeners for the same event. They run in registration order:
$events->listen('user.registered', function ($user) {
// Send welcome email
});
$events->listen('user.registered', function ($user) {
// Log registration
});
$events->listen('user.registered', function ($user) {
// Notify admin
});
Checking for Listeners #
if ($events->hasListeners('cache.cleared')) {
// At least one listener is registered
}
Listing Registered Events #
$eventNames = $events->getEvents();
// ['page.saved', 'user.registered', ...]
Removing Listeners #
Remove all listeners for an event:
$events->forget('page.saved');
Common Patterns #
Cache Invalidation #
$events->listen('page.saved', function ($page) {
app('cache.tags')->flush('pages');
app('cache')->delete('page:' . $page['slug']);
});
$events->listen('page.deleted', function ($page) {
app('cache.tags')->flush('pages');
});
Audit Logging #
$events->listen('page.saved', function ($page) {
app('logger')->info('Page saved', [
'slug' => $page['slug'],
'user' => auth_user()?->id,
]);
});
Webhooks #
$events->listen('order.completed', function ($order) {
// Queue webhook notification
dispatch(new SendWebhook('order.completed', $order));
});
Registering in Service Providers #
The best place to register listeners is in your service provider's boot() method:
class BlogServiceProvider extends ServiceProvider
{
public function boot(): void
{
$events = $this->app->make('events');
$events->listen('page.saved', [$this, 'onPageSaved']);
$events->listen('page.deleted', [$this, 'onPageDeleted']);
}
public function onPageSaved(array $page): void
{
// Handle event
}
}
Best Practices #
- Keep listeners fast - don't do heavy work synchronously
- Don't modify core flow - events are for side effects, not control
- Use descriptive names -
entity.actionformat works well - Pass minimal data - include IDs rather than full objects when possible
- Handle failures gracefully - one listener failing shouldn't break others