イベントシステム
- イベントとリスナーの生成
- #イベントの手動登録
- ワイルドカード イベント リスナー
- 手動アクセス キュー
- イベントの定義
- イベント伝播の停止
- イベント リスナー キュー
- カスタム キュー接続とキュー名
- イベントの配布 イベント サブスクライバーの登録
- #
- 概要
- イベントとリスナーの登録
- 定義イベント
- 定義リスナー
- #イベント リスナー キューイベントの配布
- イベント サブスクライバー
- イベント サブスクライバーの書き込み
イベントシステム
ディレクトリに保存され、これらのイベント クラスのリスナーは
app/Listeners ディレクトリに保存されます。アプリケーションにこれらのディレクトリが表示されない場合でも、心配する必要はありません。Artisan コンソール コマンドを使用してイベントとリスナーを生成すると、これらのディレクトリは自動的に作成されます。 イベント システムは、単一のイベントに互いに独立した複数のリスナーを持つことができるため、アプリケーションのさまざまな側面を分離する優れた方法を提供します。たとえば、注文が発送されるたびにユーザーに Slack 通知をプッシュしたい場合があります。注文処理コードと Slack 通知コードを結合する代わりに、リスナーが受信して Slack 通知に変換できる
OrderShipped
イベントを単純に発生させることができます。
#Laravel アプリケーションでのイベントとリスナーの登録
listen
属性には、すべてのイベント (キー) とイベントに対応するリスナー (値) の配列が含まれます。もちろん、アプリケーションのニーズに応じて、listen 属性に含まれる配列に複数のイベントを追加できます。たとえば、
OrderShipped イベントを追加しましょう:
/** * 应用程序的事件监听器映射 * * @var array */ protected $listen = [ 'App\Events\OrderShipped' => [ 'App\Listeners\SendShipmentNotification', ], ];
イベントとリスナーの生成
もちろん、イベント ファイルとリスナー ファイルを手動で作成するのは面倒です。ここで必要なのは、リスナーとイベントを EventServiceProvider
に追加し、event:generate
コマンドを使用することだけです。このコマンドは、EventServiceProvider
にリストされているすべてのイベントとリスナーを生成します。もちろん、既存のイベントとリスナーは変更されません。
php artisan event:generate
イベントを手動で登録する
通常、イベントはEventServiceProvider
の $listen
配列に登録されますが、EventServiceProvider
の boot
メソッドのクロージャに基づいて手動で登録することもできます。パッケージのイベント:
/** * 注册应用中的其它事件 * * @return void */ public function boot(){ parent::boot(); Event::listen('event.name', function ($foo, $bar) { // }); }
ワイルドカード イベント リスナー
リスナーを登録するときに、ワイルドカード パラメーターとして # を使用できます。同じリスナーで複数のイベントをキャプチャします。ワイルドカード リスナーは、最初の引数としてイベント名を受け取り、2 番目の引数としてイベント データ配列全体を受け取ります。
Event::listen('event.*', function ($eventName, array $data) { // });
Define events
イベントクラスは、イベントに関する情報を保存するコンテナです。たとえば、生成した OrderShipped
イベントが Eloquent ORM オブジェクトを受信すると仮定します。
<?php namespace App\Events; use App\Order; use Illuminate\Queue\SerializesModels; class OrderShipped{ use SerializesModels; public $order; /** * 创建一个事件实例。 * * @param \App\Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } }
ご覧のとおり、このイベント クラスには他のロジックが含まれていません。これは、購入した Order
インスタンスの単なるコンテナです。 PHP の serialize
関数を使用してイベント オブジェクトをシリアル化する場合、イベントで使用される SerializesModels
トレイトにより、Eloquent モデルが適切にシリアル化されます。
リスナーの定義
次に、例のイベントのリスナーを見てみましょう。イベント リスナーは、handle
メソッドでインスタンスを受け取ります。 event:generate
コマンドは、正しいイベント クラスを自動的にロードし、イベント タイプのヒントを handle
メソッドに追加します。 handle
メソッドでは、イベントに応じて必要なアクションを実行できます。
<?php namespace App\Listeners; use App\Events\OrderShipped; class SendShipmentNotification{ /** * 创建事件监听器。 * * @return void */ public function __construct() { // } /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { // 使用 $event->order 来访问 order ... } }
{tip} イベント リスナーは、コンストラクターの型ヒントに依存関係を追加することもできます。すべてのイベント リスナーは Laravel のサービス コンテナを通じて解決されるため、すべての依存関係が自動的に挿入されます。
イベント伝播の停止
リスナーの handle
メソッドで false
を返すことでこれを行うことができる場合があります。 . イベントが他のリスナーによって取得されるのを防ぐため。
イベント リスナー キュー
リスナーが電子メールの送信や HTTP リクエストの作成などの遅いタスクを実行したい場合は、それをキューにスローして処理することを選択できます。キュー リスナーの使用を開始する前に、サーバーまたはローカル開発環境でキューを構成し、キュー リスナーを開始できることを確認してください。
キューを開始するリスナーを指定するには、ShouldQueue
インターフェイスをリスナー クラスに追加します。 Artisan コマンド event:generate
によって生成されたリスナーには、このインターフェイスが現在の名前空間にインポートされているため、直接使用できます。
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ // }
以上です。このリスナーがイベントによって呼び出されると、イベント ディスパッチャーは自動的に Laravel のキュー システムを使用します。キュー内のリスナーの実行時に例外がスローされなかった場合、タスクは実行完了後にキューから自動的に削除されます。
カスタム キュー接続とキュー名
イベント リスナーによって使用されるキューの接続と名前をカスタマイズする場合は、リスナー クラスで行うことができます。 $connection
、$queue
、または $lay
プロパティを定義します:
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ /** * The name of the connection the job should be sent to. * * @var string|null */ public $connection = 'sqs'; /** * The name of the queue the job should be sent to. * * @var string|null */ public $queue = 'listeners'; /** * The time (seconds) before the job should be processed. * * @var int */ public $delay = 60; }##キューへの手動アクセスリスナーの下にあるキュー タスクの
delete メソッドと
release メソッドに手動でアクセスする必要がある場合は、 # を使用できます。 ##Illuminate\ Queue\InteractsWithQueue
トレイトを実装します。この特性はデフォルトで生成されたリスナーにロードされ、次のメソッドへのアクセスを提供します: <?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue{
use InteractsWithQueue;
/**
* 处理事件。
*
* @param \App\Events\OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
if (true) {
$this->release(30);
}
}
}
イベントリスナーのキュータスクが失敗する場合があります。リスナーのキュー タスクがキューに定義された最大試行回数を超える場合、リスナーで
failed メソッドが呼び出されます。 failed
メソッドは、イベント インスタンスと失敗の原因となった例外をパラメータとして受け取ります: <?php
namespace App\Listeners;use App\Events\OrderShipped;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue{
use InteractsWithQueue;
/**
* 处理事件。
*
* @param \App\Events\OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
//
}
/**
* 处理失败任务。
*
* @param \App\Events\OrderShipped $event
* @param \Exception $exception
* @return void
*/
public function failed(OrderShipped $event, $exception)
{
//
}
}
イベントを配布したい場合は、イベント インスタンスをヘルパー関数
event に渡すことができます。このヘルパー関数は、イベントに対応するすべての登録リスナーにイベントを配布します。 event
ヘルパー関数はグローバルに使用でき、アプリケーション内のどこからでも呼び出すことができます。 <?php
namespace App\Http\Controllers;
use App\Order;use App\Events\OrderShipped;
use App\Http\Controllers\Controller;
class OrderController extends Controller{
/**
* 将传递过来的订单发货
*
* @param int $orderId
* @return Response
*/
public function ship($orderId)
{
$order = Order::findOrFail($orderId);
// 订单发货逻辑 ...
event(new OrderShipped($order));
}
}
イベントサブスクライバー
イベント サブスクライバの作成
イベント サブスクライバは、それ自体内で複数のイベントをサブスクライブできるクラスです。つまり、単一のクラスで複数のイベント ハンドラを定義できます。サブスクライバーは、イベント ディスパッチャ インスタンスを受け取る subscribe
メソッドを定義する必要があります。特定のイベント ディスパッチャーで listen
メソッドを呼び出すことで、イベント リスナーを登録できます。
<?php namespace App\Listeners; class UserEventSubscriber{ /** * 处理用户登录事件。 */ public function onUserLogin($event) {} /** * 处理用户注销事件。 */ public function onUserLogout($event) {} /** * 为订阅者注册监听器 * * @param \Illuminate\Events\Dispatcher $events */ public function subscribe($events) { $events->listen( 'Illuminate\Auth\Events\Login', 'App\Listeners\UserEventSubscriber@onUserLogin' ); $events->listen( 'Illuminate\Auth\Events\Logout', 'App\Listeners\UserEventSubscriber@onUserLogout' ); } }
Register Eventサブスクライバ
サブスクライバを作成した後、イベント ディストリビュータを通じてサブスクライバを登録できます。 EventServiceProvider
の $subscribe
プロパティでサブスクライバーを登録できます。たとえば、UserEventSubscriber
を配列リストに追加してみましょう。
<?php namespace App\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider{ /** * 应用中事件监听器的映射。 * * @var array */ protected $listen = [ // ]; /** * 需要注册的订阅者类。 * * @var array */ protected $subscribe = [ 'App\Listeners\UserEventSubscriber', ]; }