したがって、laravel event doc によると、リスナーを定義するときに、handleメソッドでイベントインスタンスを受信し、必要なロジックを実行できます。
public function handle(FoodWasPurchased $event)
したがって、私のFoodWasPurchasedイベントが次のように定義されている場合(EventServiceProviderが設定されていると仮定):
public function __construct(Food $food)
{
$this->food = $food;
}
次のようにして、リスナーからイベントの$ foodにアクセスできます。
$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...
}
もっと良い方法があると確信しています。
または、ベストプラクティスは、1人のリスナーが1つのイベントのみをリッスンするようにすることです。
Event Subscribers を使用して複数のイベントをリッスンできます。これは、Listenersフォルダーに配置されますが、複数のイベントをリッスンできます。
<?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)
私はこれをユニットテストしました。すべてのシナリオに適しているとは限りませんが、機能しているようです。お役に立てば幸いです。
次のようなものも試すことができます。
// 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;
}
}
次に、リスナーのhandle
メソッドで、次のようにします。
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
}
}
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
3- SendNewMessageNotificationToRecipients.php(リスナー)の場合:
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');
}
}