Laravel 事件和監聽器

Laravel 的事件提供了一個簡單的觀察者模式,允許訂閱和監聽應用程序中發生的各種事件。事件類通常存儲在app/Events目錄中,而它們的監聽器存儲在app/Listeners,可以利用php artisan make來創建相關檔案。

事件在應用程式解藕相當好用,例如:如果希望在商家創建時通知使用者,無須將商家創建的代碼與通知使用者代碼放在一起,可以引發一個App\Events\StoreCreated事件,監聽器可以接收並使用該事件來分派通知。

創建事件和監聽器

首先先創建StoreCreated事件和NotifyStoreCreated監聽器,使用以下 artisan 指令來創建。

php artisan make:event StoreCreated
php artisan make:listener NotifyStoreCreated --event="StoreCreated"

上面的指令將分別在 app/Eventsapp/Listeners 文件夾中創建事件和監聽器。

註冊事件和監聽器

app/Providers/EventServiceProvider.php文件中註冊您的事件和偵聽器。

protected $listen屬性包含所有事件及其偵聽器作為鍵值對的數組。接下來,我們將事件StoreCreated和偵聽器添加NotifyStoreCreated到數組$listen中,如下所示。

use App/Events/StoreCreated;
use App/Listeners/NotifyStoreCreated;

class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
StoreCreated::class => [
NotifyStoreCreated::class,
]
];

//...
}

可以使用此指令php artisan event:list查看應用程序註冊的所有事件和偵聽器的列表

定義事件和監聽器

編輯StoreCreated.php,我們要在每次商家創建時發送通知,我們需要將$store的實例傳給StoreCreated,讓監聽器可以訪問$store的實例

# app/Events/StoreCreated.php
<?php

namespace App\Events;

....
use App\Post;

class StoreCreated
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public $store;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Store $store)
{
$this->$store = $store;
}
}

再來編輯NotifyStoreCreated.phpNotifyStoreCreated監聽器類別將用來發送通知給用戶,可以看到有一個handle函式,是事件將調用的方法,在這個handle方法中,我們將編寫必要的代碼來發送通知。

# app/Listeners/NotifyPostCreated.php

<?php

namespace App\Listeners;

use App\Events\StoreCreated;
use App\Notifications\StoreNotification;
use App\User;
use Mail;

class NotifyStoreCreated
{
....
....

/**
* Handle the event.
*
* @param StoreCreated $event
* @return void
*/
public function handle(StoreCreated $event)
{
// 要發送通知對象邏輯
$users = User::all();

foreach($users as $user) {
// 傳入$store實例,發送通知
$user->notify(new StoreNotification($event->store));
}
}
}

調度事件

最後一步就是觸發StoreCreated事件,使用event()這個helper函式,這個函式會把事件分派給有註冊的監聽器(listeners)

# app/Http/Controllers/StoreController.php

<?php

namespace App\Http\Controllers;

use App\Events\StoreCreated;
use App\Http\Controllers\Controller;
use App\Model\Store;

class StoreController extends Controller
{
//...

public function store(Request $request)
{
// 商家新增時邏輯

event(new StoreCreated($store));
}
}

如果事件使用Illuminate\Foundation\Events\Dispatchabletrait,可以像這樣調用事件的靜態dispatch方法。

public function store(Request $request)
{
// 商家新增時邏輯

StoreCreated::dispatch($store);
}

之後在商家新增時StoreCreated都會引發事件並最終執行偵聽NotifyStoreCreated監聽器以通知用戶。

補充資料