Events Laravel侦听器侦听多个事件
因此,根据laravel事件,在定义侦听器时,它可以在其handle方法中接收事件实例,并执行任何必要的逻辑:Events Laravel侦听器侦听多个事件,events,laravel,laravel-5,Events,Laravel,Laravel 5,因此,根据laravel事件,在定义侦听器时,它可以在其handle方法中接收事件实例,并执行任何必要的逻辑: public function handle(FoodWasPurchased $event) 因此,如果myFoodWasPurchased事件定义如下(假定设置了EventServiceProvider): 我可以通过以下操作从listener访问$food in事件: $event->food->doSomething(); 但现在我的问题是,如果一个听众听多个事
public function handle(FoodWasPurchased $event)
因此,如果myFoodWasPurchased事件定义如下(假定设置了EventServiceProvider):
我可以通过以下操作从listener访问$food in事件:
$event->food->doSomething();
但现在我的问题是,如果一个听众听多个事件会怎么样
Event FoodWasPurchased -> Listener Bill
Event DrinksWasPurchased -> Listener Bill
我现在做的是没有在侦听器句柄方法中指定事件实例:
public function handle($event)
稍后我可以使用if条件检查$event中接收到的内容:
if (isset($event->food)) {
// Do something...
} elseif (isset($event->drinks)) {
// Do something else...
}
我相信有更好的办法
或者最好的做法是确保一个侦听器只侦听一个事件?您也可以尝试以下方法:
//使用父类型代替食物或饮料
使用Illumb\Database\Elount\Model;
类扩展事件
{
//而不是食物或饮料
公共功能构造(模型$Model)
{
//使用通用名称代替$this->food或$this->drink
$this->item=$model;
}
}
然后在listener的handle
方法中尝试以下操作:
公共函数句柄(\App\Events\Event$Event)
{
如果($event->item instanceof\App\Food)
{
$item->eat();//只是一个例子
}
if($event->item instanceof\App\Drink)
{
$item->drink();//只是一个例子
}
}
您可以使用侦听器来侦听多个事件,这些事件位于侦听器文件夹中,但可以侦听多个事件
<?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'
);
}
}
如果您的事件符合约定或接口,您似乎可以将任意数量的事件传递给侦听器
class MyEventOne extends Event implements MyEventInterface
然后在EventServiceProvider中连接事件和侦听器,以便
protected $listen = [
'App\Events\MyEventOne' => [
'App\Listeners\MyListener',
],
'App\Events\MyEventTwo' => [
'App\Listeners\MyListener',
],
];
最后,在侦听器中键入提示处理程序接受基于契约/接口的事件对象
public function handle(MyEventInterface $event)
我已经对此进行了单元测试,它可能不适用于所有场景,但似乎可以工作。我希望它能有所帮助。1-添加到EventServiceProvider:
'App\Events\NewMessageSent' => [
'App\Listeners\SendNewMessageNotificationToRecipients',
],
'App\Events\MessageReplied' => [
'App\Listeners\SendNewMessageNotificationToRecipients',
],
'App\Events\MessageForwarded' => [
'App\Listeners\SendNewMessageNotificationToRecipients',
],
2-生成事件和侦听器:
php artisan event:generate
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');
}
}
3-在SendNewMessageNotificationToRecipients.php(侦听器)上:
这确实增加了可读性。但是如果一个听众听了两个以上的事件呢?(或者最好的方法是确保所有事件都传递相同类型的实例?)如果使用PHPStorm,您可以省略$event
的类型提示,而使用@param doc。好主意!非常感谢。我们如何从控制器调用此类?当引发相应的事件时,将触发EventListeners。因此,您必须在控制器内触发事件。此解决方案非常干净,并强制执行接口++
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');
}
}