Event事件

event事件處理
webman/event
提供一種精巧的事件機制,可實現(xiàn)在不侵入代碼的情況下執(zhí)行一些業(yè)務邏輯,實現(xiàn)業(yè)務模塊之間的解耦。典型的場景如一個新用戶注冊成功時,只要發(fā)布一個自定義事件如user.register
,各個模塊遍能收到該事件執(zhí)行相應的業(yè)務邏輯。
安裝
composer require webman/event
訂閱事件
訂閱事件統(tǒng)一通過文件config/event.php
來配置
<?php
return [
'user.register' => [
[app\event\User::class, 'register'],
// ...其它事件處理函數(shù)...
],
'user.logout' => [
[app\event\User::class, 'logout'],
// ...其它事件處理函數(shù)...
]
];
說明:
user.register
user.logout
等是事件名稱,字符串類型,建議小寫單詞并以點(.
)分割- 一個事件可以對應多個事件處理函數(shù),調(diào)用順序為配置的順序
事件處理函數(shù)
事件處理函數(shù)可以是任意的類方法、函數(shù)、閉包函數(shù)等。
例如創(chuàng)建事件處理類 app/event/User.php
(目錄不存在請自行創(chuàng)建)
<?php
namespace app\event;
class User
{
function register($user)
{
var_export($user);
}
function logout($user)
{
var_export($user);
}
}
發(fā)布事件
使用 Event::dispatch($event_name, $data);
或 Event::emit($event_name, $data);
發(fā)布事件,例如
<?php
namespace app\controller;
use support\Request;
use Webman\Event\Event;
class User
{
public function register(Request $request)
{
$user = [
'name' => 'webman',
'age' => 2
];
Event::dispatch('user.register', $user);
}
}
發(fā)布事件有兩個函數(shù),Event::dispatch($event_name, $data);
和 Event::emit($event_name, $data);
二者參數(shù)一樣。
區(qū)別是emit內(nèi)部會自動捕獲異常,也就是說如果一個事件有多個處理函數(shù),某個處理函數(shù)發(fā)生異常不會影響其它處理函數(shù)的執(zhí)行。
而dispatch則內(nèi)部不會自動捕獲異常,當前事件的任何一個處理函數(shù)發(fā)生異常,則停止執(zhí)行下一個處理函數(shù)并直接向上拋出異常。
提示
參數(shù)$data可以是任意的數(shù)據(jù),例如數(shù)組、類實例、字符串等
通配符事件監(jiān)聽
通配符注冊監(jiān)聽允許您在同一個監(jiān)聽器上處理多個事件,例如config/event.php
里配置
<?php
return [
'user.*' => [
[app\event\User::class, 'deal']
],
];
我們可以通過事件處理函數(shù)第二個參數(shù)$event_data
獲得具體的事件名
<?php
namespace app\event;
class User
{
function deal($user, $event_name)
{
echo $event_name; // 具體的事件名,如 user.register user.logout 等
var_export($user);
}
}
停止事件廣播
當我們在事件處理函數(shù)里返回false
時,該事件將停止廣播
閉包函數(shù)處理事件
事件處理函數(shù)可以是類方法,也可以是閉包函數(shù)例如
<?php
return [
'user.login' => [
function($user){
var_dump($user);
}
]
];
查看事件及監(jiān)聽器
使用命令 php webman event:list
查看項目配置的所有事件及監(jiān)聽器
注意事項
event事件處理并不是異步的,event不適合處理慢業(yè)務,慢業(yè)務應該用消息隊列處理,例如webman/redis-queue