事件機制的實現有兩種途徑:通過監聽、通過訂閱
一、通過監聽
1、創建監聽類:在命令行模式下進入框架根目錄執行
php think make:listener
例如:
php think make:listener UserListener
執行之后將在applistener下生成UserListener這個類。
立即學習“PHP免費學習筆記(深入)”;
2、配置監聽:在appevent.php這個文件的listen數組中配置UserListener這個類,如下:
‘listen’ ? ?=> [
? ? ‘testEvent’ => [‘applistenerUserListener’]
],
3、觸發監聽:在你需要觸發監聽的地方加入如下代碼
event('testEvent');
注意:這里的參數testEvent即為事件名稱,可隨便定義,但必須要與在event.php文件里配置的鍵名一致。
觸發監聽時你可以帶上第二個參數。通過第二個參數你可以把任何數據傳遞到UserListener這個類中,也就是handle方法的參數(不明白啥意思的結合下面的完整代碼理解)。
4、處理監聽邏輯:在UserListener類的handle方法中完成業務邏輯
完整代碼如下
Other:一個用來測試的類
<?php namespace appcontroller; class Other { public function hello() { echo 'hello function'; } }
Index:觸發監聽的類
<?php namespace appcontroller; use appBaseController; class Index extends BaseController { public $name = 'index'; public function test1() { //觸發監聽事件,無參數 event('testEvent'); } public function test2() { //觸發監聽事件,傳遞字符串 event('testEvent', 'hello'); } public function test3() { //觸發監聽事件,傳遞自身類 event('testEvent', $this); } public function test4() { //觸發監聽事件,傳遞其他類 $other = new Other(); event('testEvent', $other); } }
UserListener:事件監聽類
<?php namespace applistener; class UserListener { /** * 事件監聽處理 * * @return mixed */ public function handle($event) { //當調用Index類的test1方法時該代碼有效,$event為null var_dump($event); //當調用Index類的test2方法時該代碼有效,$event為字符串hello var_dump($event); //當調用Index類的test3方法時該代碼有效,$event為Index類的實例 //可以訪問Index類的name變量 echo $event->name; ????????//當調用Index類的test4方法時該代碼有效,$event為Other類的實例 ????????//可以調用Other類的hello方法 ????????echo?$event->hello(); ????} }
二、通過訂閱
1、創建訂閱類
在命令行模式下進入框架根目錄執行
php think make:subscribe
例如:
php think make:subscribe UserSubscribe
執行之后將在appsubscribe下生成UserSubscribe這個類。
2、配置監聽
在appevent.php這個文件的subscribe數組中配置UserSubscribe這個類,如下:
‘subscribe’ => [‘appsubscribeUserSubscribe’],
注意:為了測試效果,要把上面配置的UserListener從listen數組刪除掉
3、觸發監聽
跟第一種途徑一樣
4、處理監聽邏輯
處理監聽的邏輯又有兩種方法,我稱之為自動綁定和手動綁定。手動綁定和自動綁定是互斥的,只能二選一。
4.1 自動綁定
完成業務邏輯的ontestEvent方法應該被添加到UserSubscribe類中。添加的方法名不能隨意定義,規則是事件名稱前面加上on。因為我們在event.php里定義的事件名稱是testEvent,所以方法名就是ontestEvent(注意大小寫)。監聽方法定義之后就自動與事件綁定,所以我稱之為自動綁定。
完整代碼如下
Other和Index類的代碼跟第一種途徑一樣
UserSubscribe:事件訂閱類
<?php namespace appsubscribe; class UserSubscribe { public function ontestEvent($user) { //當調用Index類的test1方法時該代碼有效,$event為null var_dump($user); //當調用Index類的test2方法時該代碼有效,$event為字符串hello var_dump($user); //當調用Index類的test3方法時該代碼有效,$event為Index類的實例 //可以訪問Index類的name變量 echo $user->name; ????????//當調用Index類的test4方法時該代碼有效,$event為Other類的實例 ????????//可以調用Other類的hello方法 ????????echo?$user->hello(); ????} }
4.2 手動綁定
首先,創建事件類,負責處理具體的業務邏輯。在命令行模式下進入框架根目錄執行:
php think make:event
例如:
php think make:event UserEvent
執行之后將在appevent下生成UserEvent這個類。
再在該類中定義一個handle方法,該方法有一個傳入參數。方法名和傳入的參數名可以任意定義。具體的業務邏輯就可以放在handle方法里面處理。
接下來,在UserSubscribe類里面新增subscribe方法,該方法需要接收一個Event對象作為參數。接著,在該函數里將事件監聽綁定到UserEvent類的handle方法上。如下:
$event->listen('testEvent',?[app('appeventUserEvent'),?'handle']);
完整代碼如下
Other和Index類的代碼跟第一種途徑一樣
UserSubscribe:事件訂閱類
<?php declare (strict_types = 1); namespace appsubscribe; use thinkEvent; class UserSubscribe { public function subscribe(Event $event) { $event->listen('testEvent',?[app('appeventUserEvent'),?'handle']); ????} }
UserEvent:事件處理類
<?php declare (strict_types = 1); namespace appevent; class UserEvent { public function handle($user) { //當調用Index類的test1方法時該代碼有效,$user為null var_dump($user); //當調用Index類的test2方法時該代碼有效,$user為字符串hello var_dump($user); //當調用Index類的test3方法時該代碼有效,$user為Index類的實例 //可以訪問Index類的name變量 echo $user->name; ????????//當調用Index類的test4方法時該代碼有效,$user為Other類的實例 ????????//可以調用Other類的hello方法 ????????echo?$user->hello(); ????} }