タグ: Listener

  • 【Laravel】EventとListenerについて

    【Laravel】EventとListenerについて

    仕事で既存の機能に新しい機能を追加しようと思っていた時に、既存の機能に「Event」などとこうものがあった。

    初めて聞いた用語だったので、どのようなものなのか調べてみた。

    Eventに対してListener

    僕が見たコードはEventしかなかったが、実はこのEventというのはListenerというヤツとセットになっている。

    一心同体である。

    簡単に言うと、Eventはイベント発火の「合図」の役割を担っている。

    それに対して、Listenerはその合図を実際に感知してイベントを「実行」する役割を担っている。

    Eventの長所の1つは、1つのEventが複数のListenerを実行させることができる点である。

    それを紐づけるEventServiceProvider

    先ほど紹介したEventとListenerは勝手に連動してイベントを実行するわけではない。

    これらは今紹介している「EventServiceProvider」によって紐づけられ、特定にEventには特定の Listenerが実行されるようになっている。

    Eventの書き方

    通常Eventはapp/Eventsディレクトリに書く。

    デフォルトの状態ではEventsディレクトリは存在しないかも知れないが、Atrisanコマンドによって簡単に生成できる。

    <?php
    use App\User;
    // 以下略
    
    class UserRegistered
    {
        use Dispatchable, InteractsWithSockets, SerializesModels;
        public $user;
        public function __construct(User $user)
        {
            $this->user = $user;
        }
    }

    正直よく分からん。

    Listenerの書き方

    一方でListenerは通常app/Listenersディレクトリに書く。

    artisanによって生成されるListenerファイルはhandleメソッドがデフォルトで用意されている。

    このhandleメソッドにはEventによって実際に実行される内容を書く。

    <?php
    namespace App\Listeners;
    
    use App\Events\UserRegistered;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    use Mail;
    use App\Mail\WelcomeMail;
    
    class SendWelcomeEmail
    {
        public function __contruct()
        {
            //
        }
    
        public function handle(UserRegistered $event)
        {
            Mail::to($event->user->email)->send(new WelcomeMail());
        }
    }

    EventServiceProviderに書き方

    EventServiceProviderファイルはApp\Providersディレクトリに書く。

    ここにlistenプロパティに、実際に紐づけたEventとListenerを書いていく。

    <?php
    namespace App\Providers;
    
    use App\Events\UserRegistered;
    use App\Events\SendWelcomeEmail;
    use App\Events\RegisterMailMagazine;
    
    class EventServideProvider extends ServiceProvider
    {
        protected $listen = [
            UserRegisterd::class => [
                SendWelcomeEmail::class,
                RegisterMailMagazine::class,
            ],
            // 続く
        ];
    
        public function boot()
        {
            parent::boot();
            //
        }
    }

    Eventを発火させる

    • Event(発火)
    • Listener(実行)
    • EventServiceProvider(紐付け)

    の3つを完了したから、あとは最初の発火をさせるコードを書くだけ。

    例えばRegisterController.phpのcreateメソッドの中でeventヘルパー関数を使って、イベントを発火させるとする。

    <?php
    use App\Events\UserRegistered;
    
    protected function create(array $data)
    {
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password'])
        ]);
    
        event(new UserRegister($user));
    
        return $user;
    }

    こんな感じでEventを実行させたいタイミングでeventヘルパー関数を用いると、Eventが発火して、Listenerが内容を実行してくれる。