Laravel listener listens for several events

Thus, according to the laravel doc event, when defining listeners, it can receive an instance of the event in the descriptor method and any logic must be executed:

public function handle(FoodWasPurchased $event) 

So, if my FoodWasPurchased event is defined below (it is assumed that an EventServiceProvider is set):

 public function __construct(Food $food) { $this->food = $food; } 

I could access $ food in the event from the listener by doing:

 $event->food->doSomething(); 

But now my question is, what if the listener listens for several events?

 Event FoodWasPurchased -> Listener Bill Event DrinksWasPurchased -> Listener Bill 

Now I did not specify an instance of the event in the listener method method:

 public function handle($event) 

where can I use the if condition later to check what is received in the $ event:

 if (isset($event->food)) { // Do something... } elseif (isset($event->drinks)) { // Do something else... } 

I am sure there is a better way.

Or is it best to make sure that one listener is only listening to one event?

+8
events laravel laravel-5
source share
4 answers

You can listen to several events using event subscribers , which are placed in the Listeners folder, but can listen to several 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' ); } } 
+12
source share

You can also try something like this:

 // Instead of Food or Drink use parent Type use Illuminate\Database\Eloquent\Model; class DrinWasPurchased extends Event { // Instead of Food or Drink typehint Model public function __construct(Model $model) { // Instead of $this->food or $this->drink use a generic name $this->item = $model; } } 

Then in the listener's handle method try something like this:

 public function handle(\App\Events\Event $event) { if($event->item instanceof \App\Food) { $item->eat(); // Just an example } if($event->item instanceof \App\Drink) { $item->drink(); // Just an example } } 
+4
source share

If your events match the contract or interface, it seems you can pass as many as you want to the listener ...

 class MyEventOne extends Event implements MyEventInterface 

Then in EventServiceProvider you hook your events and listeners like this ...

 protected $listen = [ 'App\Events\MyEventOne' => [ 'App\Listeners\MyListener', ], 'App\Events\MyEventTwo' => [ 'App\Listeners\MyListener', ], ]; 

And finally, in your listener, you enter a hint from your handler to accept an event object based on a contract / interface ...

 public function handle(MyEventInterface $event) 

I tested this device, maybe this is not suitable for each scenario, but it seems to work. Hope this helps.

+4
source share

1- Add to EventServiceProvider:

 'App\Events\NewMessageSent' => [ 'App\Listeners\SendNewMessageNotificationToRecipients', ], 'App\Events\MessageReplied' => [ 'App\Listeners\SendNewMessageNotificationToRecipients', ], 'App\Events\MessageForwarded' => [ 'App\Listeners\SendNewMessageNotificationToRecipients', ], 

2- Generate events and listener:

 php artisan event:generate 

3- On SendNewMessageNotificationToRecipients.php (listener):

 use App\Events\Event; use App\Events\NewMessageSent; use App\Events\MessageReplied; use App\Events\MessageForwarded; public function handle(Event $event) { if ($event instanceof NewMessageSent) { dd('message sent'); } else if ($event instanceof MessageReplied) { dd('message replied'); } else if ($event instanceof MessageForwarded) { dd('message forwarded'); } } 
0
source share

All Articles