laravel5.5事件系統
1 註冊事件和監聽器
1、修改EventServiceProvider中的listen陣列
/**
* 應用程式的事件監聽器對映。
*
* @var array
*/
protected $listen = [
'App\Events\OrderShipped' => [
'App\Listeners\SendShipmentNotification',
],
];
2、建立相應檔案
php artisan event:generate
執行上面命令後,根據上面修改的listen陣列,會在app目錄下會生成相應的資料夾和檔案
2 定義事件
修改App\Events\OrderShipped.php檔案
<?php namespace App\Events; use App\Order; use Illuminate\Queue\SerializesModels; class OrderShipped { use SerializesModels; public $order; /** * 建立一個事件例項。 * * @param Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } }
3 定義監聽器
<?php namespace App\Listeners; use App\Events\OrderShipped; class SendShipmentNotification { /** * 建立事件監聽器。 * * @return void */ public function __construct() { //你的事件監聽器也可以在建構函式中加入任何依賴關係的型別提示。 //所有的事件監聽器都是通過 Laravel 的 服務容器 來解析的,因此所有的依賴都將會被自動注入。 } /** * 處理事件 * * @param OrderShipped $event * @return void */ public function handle(OrderShipped $event) { /******************************************** * * 1.當你分發事件之後,這裡你可以實現你想做的事情 ... * 2.如果一個事件有多個監聽器,這裡返回false則不會再被其他的監聽器獲取 */ //用 $event->order 來訪問 order ... dd($event); //return false; } }
4 分發事件
可以使用全域性輔助函式event(),可以在應用的任何地方使用,將事件分發給已經註冊的監聽器上。
<?php
namespace App\Http\Controllers;
use App\Order;
use App\Events\OrderShipped;
use App\Http\Controllers\Controller;
class OrderController extends Controller
{
public function ship($orderId)
{
$order = Order::findOrFail($orderId);
//分發事件,最後dd()打印出$order
event(new OrderShipped($order));
}
}
更多使用方法
1. 可以手動註冊事件
事件通常是像上面那樣在$listen陣列中定義, 但是,也可以在 EventServiceProvider 類的 boot 方法中註冊基於事件的閉包
/**
* 註冊應用程式中的任何其他事件。
*
* @return void
*/
public function boot()
{
parent::boot();
Event::listen('event.name', function ($foo, $bar) {
//
});
//這裡還可以使用萬用字元*,在此監聽多個事件。
//萬用字元監聽器接受事件名稱作為其第一個引數,並將整個事件資料陣列作為其第二個引數:
Event::listen('event.*', function ($eventName, array $data) {
//
});
}
2. 事件監聽器中呼叫佇列
1、如果需要使用比較發郵件等比較慢的任務,則可以丟給佇列處理
只需要將讓監聽類實現ShouldQueue介面
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue
{
//
}
2、可以自定義佇列連線和名稱
監聽器類中定義 $connection 和 $queue 屬性即可
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue
{
/**
* 任務應該傳送到的佇列的連線的名稱
*
* @var string|null
*/
public $connection = 'sqs';
/**
* 任務應該傳送到的佇列的名稱
*
* @var string|null
*/
public $queue = 'listeners';
}
3、手動訪問佇列
如果你需要手動訪問監聽器下面佇列任務的 delete 和 release 方法,你可以新增 Illuminate\Queue\InteractsWithQueue trait 來實現。這個 trait 會預設載入到生成的監聽器中,並提供對這些方法的訪問:
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue
{
use InteractsWithQueue;
/**
* Handle the event.
*
* @param \App\Events\OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
if (true) {
$this->release(30);
}
}
4、處理失敗佇列
事件監聽器的佇列任務可能會失敗,而如果監聽器的佇列任務超過了佇列中定義的最大嘗試次數,則會監聽器上呼叫 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)
{
//
}
}
3.事件訂閱者
1、編寫事件訂閱者類
事件訂閱者是一個可以在自身內部訂閱多個事件的類,即能夠在單個類中定義多個事件處理器。訂閱者應該定義一個 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'
);
}
}
2、註冊事件訂閱者
在 EventServiceProvider 類的 $subscribe 屬性中註冊訂閱者
<?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',
];
}