Help us understand the problem. What is going on with this article?

Laravel5.5でEventの使用方法に関する調査

More than 1 year has passed since last update.

概要

Laravel5.5でイベントを用いた実装をするにあたり、調査した内容を共有致します。

イベントの概要については公式Docを参照して頂ければと思います。

https://readouble.com/laravel/5.5/ja/events.html

基本的に登場人物は以下の4つになります。

①イベント

②イベントリスナー

③上記2つを紐づけるサービスプロバイダー

④イベントを発火するクラス

利用方法

①App\Providers\EventServiceProviderにイベントとイベントリスナーを$listenに定義します。

 例として"TestEvent"というイベントに対して"TestListener1"と"TestListner2"の二つのリスナーを定義します。

EventServiceProvider
protected $listen = [
    'App\Events\TestEvent' => [
        'App\Listeners\TestListner1',
        'App\Listeners\TestListner2',
    ],
];

②artisanコマンドで上記で定義したリスナーを作成します。

 これでイベントファイル1つとイベントリスナーファイル2つが自動作成されたはずです。

php artisan event:generate

③これでコントローラなどからイベントを発火できます。

 イベントが発火されるとそのイベントに紐づいたリスナーのhandleメソッドが呼ばれます。

 リスナーのhandleメソッドでreturnした値はeventヘルパの返り値として取得できます。

TestController
$response = event(new TestEvent());

調査事項① イベントにパラメタを渡し、リスナーから値を返却できるか

【結論】下記の要領で出来る。

①コントローラで、イベントを発火するときにパラメタを渡す

TestController
$response = event(new TestEvent("test parameter"));

②イベントで、コンストラクタとpublicなプロパティを設定する

TestEvent
class TestEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $parameter;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($parameter)
    {
        $this->parameter= $parameter;
    }
}

③リスナーで、イベントのプロパティにアクセスする

TestListener1
class TestListener1
{
    public function handle(TestEvent $event)
    {
        return $event->parameter; //これでイベントのプロパティにアクセス可能
    }
}

④これでeventヘルパの返却値に配列で値が返ってきます。

array:1 [▼
  0 => "test parameter"
]

調査事項② 複数リスナー時の実行順番と返却値がどうなるか

【結論】複数リスナーの実行をするとき、キューを使用しない場合、EventServiceProviderに設定した順番通りに"同期実行"される

EventServiceProvider
protected $listen = [
    'App\Events\TestEvent' => [
        'App\Listeners\TestListner1', // 先に実行される、 return "listen 1"を記述してある
        'App\Listeners\TestListner2',  // 後に実行される、 return "listen 2"を記述してある
    ],
];

この状態でイベントを発火する

TestController
$response = event(new TestEvent());

$responseの中身は下記のようになる。

array:2 [▼
  0 => "listen 1"
  1 => "listen 2"
]

同期処理のため、TestListner1の処理をsleep等で遅らせてもこの順番で返却された。

調査事項③ トランザクション制御できるか

【結論】できる

試したこと

①リスナーで適当なテーブルにInsertする処理を記述

TestListner1
public function handle(TestEventInaba $event)
{
    $account = new Account;
    $account->id = 999;
    $account->is_available = 1;
    $account->login_id = "user9999";
    $account->name = "SampleName";
    $account->password = "SamplePass";
    $account->save();
}

②コントローラ側でイベント発火時にトランザクション制御を記述して実験

TestController
DB::beginTransaction();
$response = event(new TestEvent());
DB::rollback(); //またはDB::commit();

③コミットもロールバックも正常に動作することを確認

pipiox
大手化粧品メーカー営業 -> 商社営業 -> ITベンチャー -> ITフリーランスという異色の経歴。 突然嫁から「ぴぴお」と呼ばれだして気に入ったのでもうこれでいきます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away