Let’s learn how to create events and listeners in Laravel 11. Here we are creating a simple events and learn how to listen to those events. Try to understand below mention points before moving forward.
- Events are created inside the app/events directory.
- Listeners are created inside the app/listeners directory.
- php artisan make:event is used to create a event.
- php artisan make:listener is used to create a listener.
- Listeners must have either “handle” or “__invoke” method to define it as a listener. “handle” method is the commonly used one.
- Type hint event class or define type of the parameter in the “handle” method of the listener class to bind listener to event. ex: handle(CommentPosted $event){}
- Event can have multiple listeners.
- Listener can listen to multiple events.
- Can queue listener by implementing ShouldQueue interface in the listener class.
- dispatch method of the event class is used to fire an event.
- arguments passed to dispatch() method will passed to the constructor of the event class.
- Parameters in the event constructor will passed to handle() method of the listener class via $event parameter.
How to create a event that is listen by multiple listeners
Let’s create a event and make sure to listen to that event by two listeners. In simple one event class and when it fired it was listened by two listeners.
First create the event class using below artisan command.
php artisan make:event ProductAddedToCart
Next create two listener classes.
php artisan make:listener UpdateCartSummary
php artisan make:listener SendAddedNotification
Open created event class in the app/events folder. add $name parameter to constructor.
/**
* Create a new event instance.
*/
public function __construct(public string $name)
{
//
}
Open “UpdateCartSummary.php” listener class in the app/listeners directory. You can access parameters defined the constructor method of the event class via $event parameter of the listener class.
....
use App\Events\ProductAddedToCart;
....
/**
* Handle the event.
*/
public function handle(ProductAddedToCart $event): void
{
echo ("Event is ".$event->name." and ");
echo ("Listener is UpdateCartSummary<br/>");
}
Next open other listener class which is SendAddedNotification.php in the app/listeners directory.
....
use App\Events\ProductAddedToCart;
.....
/**
* Handle the event.
*/
public function handle(ProductAddedToCart $event): void
{
echo ("Event is ".$event->name." and ");
echo ("Listener is SendAddedNotification<br/>");
}
Open web.php file inside the routes directory. Add new route and fire the above defined event.
use App\Events\ProductAddedToCart;
Route::get('/events', function () {
ProductAddedToCart::dispatch('ProductAddedToCart event is fired');
});
One listener class that listen to multiple events
Let’s learn how to create a listener class that can listen to multiple events. Here we are creating a single listener class and two event classes. When firing both event classes it will be listened by a single listener class.
First create two event classes using below artisan command.
php artisan make:event CommentsPosted
php artisan make:event ProductAddedToCart
Next create a single listener class to listen for above 2 events
php artisan make:listener NotifyProductOwner
Open CommentsPosted.php event in the app/Events directory. Add $name parameter to the constructor.
/**
* Create a new event instance.
*/
public function __construct(public string $name)
{
//
}
Next open ProductAddedToCart.php in the app/Events directory. Add $name parameter to the constructor.
/**
* Create a new event instance.
*/
public function __construct(public string $name)
{
//
}
Next open the NotifyProductOwner.php listener class in the app/Listeners directory. Then bind above defined two event classes to this listener class using handle() method by type hinting the parameter.
.....
use App\Events\CommentPosted;
use App\Events\ProductAddedToCart ;
.....
/**
* Handle the CommentPosted Event
*/
public function handle(CommentPosted | ProductAddedToCart $event): void
{
echo ("Event is ".$event->name." and ");
echo ("Listener is NotifyProductOwner<br/>");
}
Fire defined event inside a controller or route. Here for simplicity I am going to fire above defined events in the web.php
use App\Events\CommentPosted;
use App\Events\ProductAddedToCart ;
Route::get('/events', function () {
CommentPosted::dispatch('CommentPosted event is fired');
ProductAddedToCart::dispatch('ProductAddedToCart event is fired');
});
How Laravel know to which events a listener class should listen
It is done by type hinting in the “handle” or “__invoke” methods in the listener class in the app/Listener directory. Type hinting is defining the type of the parameter that method is accepting. Here you can type hint the event or events that listener should listen in the “handle” method of the listener class.
Ex: listen to one event
public function handle(PodcastProcessed $event){}
Ex: listen to many events.
public function handle(PodcastProcessed|PodcastPublished $event){}