事件系統可以看成是行為系統的升級版,相比行為系統強大的地方在於事件本身可以是一個類,並且可以更好的支援事件訂閱者。
事件相比較中介軟體的優勢是事件比中介軟體更加精準定位(或者說粒度更細),並且更適合一些業務場景的擴充套件。例如,我們通常會遇到使用者註冊或者登入後需要做一系列操作,通過事件系統可以做到不侵入原有程式碼完成登入的操作擴充套件,降低系統的耦合性的同時,也降低了BUG的可能性。
步驟一:準備登入入口
首先準備一個登入入口 ,該入口本地的虛擬路由為 /api/login
class User extends BaseController { public function login() { //執行登入操作 echo "login_entrance\n" ; $user = \app\common\model\User::find(1)->toArray(); //登入成功後的操作,比如可以分配邀請獎勵,寫入登入日誌等 echo "login_after\n"; } }
步驟二:建立事件
建立UserLoginAfterEvent事件,並在config/event.php配置檔案中進行繫結
class UserLoginAfterEvent { public $user; public function __construct($user) { $this->user = $user; echo "user_login_after_event\n"; } }
'bind' => [ 'UserLoginAfter' => \app\common\event\UserLoginAfterEvent::class ],
然後在user/login 方法後面增加觸發事件程式碼
public function login() { //執行登入操作 echo "login_entrance\n" ; $user = \app\common\model\User::find(1)->toArray(); //登入成功後的操作,比如可以分配邀請獎勵,寫入登入日誌等 echo "login_after\n"; /** 觸發事件 */ // 通過事件標識 event("UserLoginAfter", $user); // 傳入事件物件例項 event(new UserLoginAfterEvent($user)); }
這時執行 /api/login 的輸出結果如下:
login_entrance login_after user_login_after_event
經過驗證 此時 使用事件標識觸發 在UserLoginAfterEvent事件中 沒有結果輸出的。
步驟三:建立監聽
建立事件監聽類 UserLoginAfterListener.php,並在config/event.php配置檔案中進行繫結
class UserLoginAfterListener { public function handle($user) { // 事件監聽處理 echo "user_login_after_listener\n"; } }
'listen' => [ 'UserLoginAfter' => [\app\common\listener\UserLoginAfterListener::class] ],
這時執行 /api/login 的輸出結果如下:
login_entrance login_after user_login_after_listener user_login_after_event user_login_after_listener
另外在 UserLoginAfterListener 中列印 $user 的結果如下:
^ array:3 [ "id" => 1 "username" => "wangqy" "password" => "123456"] ^ app\common\event\UserLoginAfterEvent {#88 +user: array:3 [ "id" => 1 "username" => "wangqy" "password" => "123456" ]}
結論
通過上述測試得出的結果如下:
1、使用事件標識來監聽時 是不走定義的事件類的,只有在event方法中傳入事件例項才能夠在事件類進行操作值。
2、通過事件標識來監聽時 ,在監聽類中接受的值,是實際在觸發事件時傳入的引數,而通過事件類例項監聽時,在監聽類中拿到的是事件類例項。
注意:
在進行監聽類繫結時,要注意標識後面的值是陣列型別,使用下面這種方式,雖然沒有報錯,但是也不會生效。
'UserLoginAfter' => \app\common\listener\UserLoginAfterListener::class
參考連結:https://www.kancloud.cn/manual/thinkphp6_0/1037492