Laravelには、イベントとリスナーという機能があります。
Laravelの公式サイトには、イベントとリスナーの作成方法は書かれているものの、イベントとはなにか、リスナーとは何かについては書かれていないようです。
エンジニアとして基礎中の基礎だから教えるまでもないということなのでしょうか。
残念ながら僕はその基礎ができていないようなのでイベントとリスナーについて調べてみました。
イベントとリスナーの関係性
https://www.ritolab.com/entry/35
こちらの記事を参考にすると、こう説明されています。
オブザーバパターンとは、デザインパターンの一つで、簡単に言うと監視される側と監視する側の関係を持つプログラム構造で、監視される側の変化(イベント=発行)を、監視する側(リスナー=購読)がキャッチして処理を行う。
イベントとリスナーの関係のことをオブザーバーパターンというらしいです。
そして、毎回混乱するのは、監視される・監視するの意味です。
監視の定義が曖昧すぎて、もっと噛み砕いてもらわないとわかりません。
なので、僕なりに噛み砕いてみました。
イベントとリスナーの書き方
イベントは監視される側らしいのですが、まず誰に監視されるのかというと、リスナーですね。ここまではわかります。
そして、何を監視されるのか、これは、イベントの中身です。
イベントは、以下のようなeventヘルパを利用することで呼び出すことができます。
event(new AccessDetection(str_random(100)));
そして、EventServiceProvider.php
にイベントが起こった時にリスナーを発動させるよう登録をしておきます。
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\Event' => [
'App\Listeners\EventListener',
],
// アクセス時にイベントを発行する側
'App\Events\AccessDetection' => [
// テキストを生成&書き込みを行うリスナー側
'App\Listeners\MakeTextListener',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
app/Events/AccessDetection.php
の中身に、値の受け渡しなどを記述しておきます。
そうすると、イベントが呼び出されたときに、リスナーで値を使うことができます。
最後に、リスナーの内容を記述します。
<?php
namespace App\Listeners;
use App\Events\AccessDetection;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class MakeTextListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param AccessDetection $event
* @return void
*/
public function handle(AccessDetection $event)
{
// テキストファイル作成
$file = sprintf('%s/%s.txt', storage_path('texts'), date('Ymd-His'));
touch($file);
// 書き込み
$current = file_get_contents($file);
$current .= $event->param;
file_put_contents($file, $current);
}
}
イベントからリスナーが発動するまでの流れ
イベントが起こって、リスナーが発動するまでの流れを整理しておきます。
- コントローラーでeventヘルパを使って、イベントを起こす
- プロバイダーに登録してあるイベントが呼び出される
- イベントに記述した値がリスナーに受け渡される
- リスナーが発動する
このような流れになります。
イベントとリスナーの使いみち
一般的には、コントローラーをコンパクトにするために使われます。
例えばメール送信機能は、ユーザ登録時、購入時、更新時などで共通して使われますが、それをコントローラーに書いていたら内容が重複してしまいます。
なので、イベントとリスナーに記述しておいて、それぞれのコントローラからイベントを起こすだけで、メール送信ができるようにしておくのです。
使いみちはいろいろありますが、メールやslackへの通知の際に使うのが一般的かなと思います。