イベントとイベントリスナ

Last-modified: Tue, 11 Sep 2018 11:26:33 JST (38d)

Laravelにはイベントという仕組みがあります。
イベント。というと何となく分からないかもしれませんが(自分だけ?)
トリガというほうが自分はしっくりきました。
ログイン時のログファイルを分離するでも利用しましたが、
作成したイベントを発生させることにより、そのイベントに対応するイベントリスナの処理を実行するというものです。
こうすることにより、イベント発生元に様々なロジックを実装しなくても、イベント発生元はイベントを発生させさえすれば、
後のイベントリスナ側の処理を感知しなくてもよい。という仕組みになっています。
ここでは実際にコントローラから独自のイベントを発生させ、それをリスナー側が処理をする例を作ってみます。

イベントとイベントリスナの作成

まずは発生させるイベントとそれを受信するイベントリスナの定義を行います。
と言ってもLaravelには自動作成の仕組みがあります。
まず、イベントとそれを受信するイベントリスナの定義をApp\Providers\EventServiceProvider.phpに以下のように追記します。

        'App\Events\DeleteUser'=>[
            'App\Listeners\LogDeleteUser'
        ],

リスナーの箇所が配列になっている点がミソです。つまり、一つのイベントに対し複数のイベントリスナを発動させることができます。
定義が追加出来たら、いつものようにひな形を作成します。

php artisan event:generate

これで、

  • App\Events\DeleteUser.php
  • App\Listeners\LogDeleteUser.php
    が自動生成されます。

イベントの作成

作成されたイベントのひな型を次のように変更します。

class DeleteUser
{
    use SerializesModels;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

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

}

ひな形で生成されたイベントから、ブロードキャストなど使用しないイベントを削除しました。
また、コンストラクタで$userを引数にとり、イベントリスナ側で参照できるようにしました。
この辺りは作成するイベント次第でしょう。
次にイベントリスナ側を作っていきます。

class LogDeleteUser
{
    /**
     * Create the event listener.
     *
     * @param Request request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Handle the event.
     *
     * @param  DeleteUser  $event
     * @return void
     */
    public function handle(DeleteUser $event)
    {
        $user = $event->user;
        Logs('authlog')->info('ユーザ削除',['user:' . $user->id]);
        $login_his_db = new LoginHistory();
        $login_his_db->record($user->id, $this->request,"ユーザ削除");
    }
}

ここでは、ユーザ削除時のイベント処理としてログファイルとDBに書き込みを行います。
書き込み時IPアドレスなどリクエスト情報が欲しいので、コンストラクタでRequestサービスを注入しています。
イベントを受信している個所はhandle()で、定義したイベントを引数にとり、実際のイベント処理を実装します。

イベントの発生

ここまでは、イベントの定義とそのリスナーを作成しました。
このままでは何も起きないので、実際にイベントを発生させます。
イベントの発生はどこでもできるようなのですが、ここではコントローラ内でユーザ削除ロジックが走る前にイベントを発生させてみます。(削除後だとユーザ情報が消えているので、削除前にイベントを発生させています。)

    public function deleteUser(Request $request){
        // 確認画面でキャンセルボタンが押された場合、自身にPostしているので戻れないので、
        //TOPへ飛ばす
        if ($request->get('action') === 'back') {
            //
            return Redirect::to('login');
        }
        //ユーザ削除

        //イベントを発生!
        event(new DeleteUser(Auth::user()));
        //ユーザ削除処理
        User::where('id',Auth::user()->id)
            ->delete();

        //ログアウトさせ、ログイン画面表示
        Auth::logout();
        return Redirect::to('login');
    }

イメージが何となくつかめたでしょうか?


Counter: 31, today: 2, yesterday: 0

このページの参照回数は、31です。