So according to the laravel event doc, when defining listeners, it can receive the event instance in their handle method and perform any logic necessary:
public function handle(FoodWasPurchased $event)
So if my FoodWasPurchased event is defined as below (assumed EventServiceProvider is set):
public function __construct(Food $food)
{
$this->food = $food;
}
I could access the $food in event from listener by doing:
$event->food->doSomething();
But now my question is what if a listener listen to multiple events?
Event FoodWasPurchased -> Listener Bill
Event DrinksWasPurchased -> Listener Bill
What I did now is I did not specify the event instance in the listener handle method:
public function handle($event)
where I can later use an if condition to check what is received in the $event:
if (isset($event->food)) {
// Do something...
} elseif (isset($event->drinks)) {
// Do something else...
}
I'm sure there is a better way.
Or the best practice is ensure that one listener only listens to one single event ?
You can listen to multiple events by using Event Subscribers which are placed in the Listeners folder but are capable of listening to multiple events.
<?php
namespace App\Listeners;
class UserEventListener{
/**
* Handle user login events.
*/
public function onUserLogin($event) {}
/**
* Handle user logout events.
*/
public function onUserLogout($event) {}
/**
* Register the listeners for the subscriber.
*
* @param Illuminate\Events\Dispatcher $events
* @return array
*/
public function subscribe($events){
$events->listen(
'App\Events\UserLoggedIn',
'App\Listeners\UserEventListener@onUserLogin'
);
$events->listen(
'App\Events\UserLoggedOut',
'App\Listeners\UserEventListener@onUserLogout'
);
}
}
If your events conform to a contract or interface it seems you can pass as many as you like to a listener...
class MyEventOne extends Event implements MyEventInterface
Then in the EventServiceProvider you connect up your events and listeners as so...
protected $listen = [
'App\Events\MyEventOne' => [
'App\Listeners\MyListener',
],
'App\Events\MyEventTwo' => [
'App\Listeners\MyListener',
],
];
And finally in your listener you type hint your handler to accept the event object based on the contract/interface...
public function handle(MyEventInterface $event)
I've unit tested this, it may not be appropriate for every scenario, but it seems to work. I hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With