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',
];
}