Events Laravel侦听器侦听多个事件

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(); 但现在我的问题是,如果一个听众听多个事

因此,根据laravel事件,在定义侦听器时,它可以在其handle方法中接收事件实例,并执行任何必要的逻辑:

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');
    }
}