Thinkphp事件機(jī)制兩種實現(xiàn)方式詳解
事件機(jī)制的實現(xiàn)有兩種途徑:通過監(jiān)聽、通過訂閱
一、通過監(jiān)聽
1、創(chuàng)建監(jiān)聽類:在命令行模式下進(jìn)入框架根目錄執(zhí)行
php think make:listener <自定義的類名>
例如:
php think make:listener UserListener
執(zhí)行之后將在<框架根目錄>\app\
listener\下生成
UserListener這個類。
2、配置監(jiān)聽:在<框架根目錄>\app\event.php這個文件的listen數(shù)組中配置UserListener這個類,如下:
'listen' => [
'testEvent' => ['app\listener\UserListener']
],
3、觸發(fā)監(jiān)聽:在你需要觸發(fā)監(jiān)聽的地方加入如下代碼
event('testEvent');
注意:這里的參數(shù)testEvent即為事件名稱,可隨便定義,但必須要與在event.php文件里配置的鍵名一致。
觸發(fā)監(jiān)聽時你可以帶上第二個參數(shù)。通過第二個參數(shù)你可以把任何數(shù)據(jù)傳遞到UserListener這個類中,也就是handle方法的參數(shù)(不明白啥意思的結(jié)合下面的完整代碼理解)。
4、處理監(jiān)聽邏輯:在UserListener類的handle方法中完成業(yè)務(wù)邏輯
完整代碼如下
Other:一個用來測試的類
<?php namespace app\controller; class Other { public function hello() { echo 'hello function'; } }
Index:觸發(fā)監(jiān)聽的類
<?php namespace app\controller; use app\BaseController; class Index extends BaseController { public $name = 'index'; public function test1() { //觸發(fā)監(jiān)聽事件,無參數(shù) event('testEvent'); } public function test2() { //觸發(fā)監(jiān)聽事件,傳遞字符串 event('testEvent', 'hello'); } public function test3() { //觸發(fā)監(jiān)聽事件,傳遞自身類 event('testEvent', $this); } public function test4() { //觸發(fā)監(jiān)聽事件,傳遞其他類 $other = new Other(); event('testEvent', $other); } }
UserListener:事件監(jiān)聽類
<?php namespace app\listener; class UserListener { /** * 事件監(jiān)聽處理 * * @return mixed */ public function handle($event) { //當(dāng)調(diào)用Index類的test1方法時該代碼有效,$event為null var_dump($event); //當(dāng)調(diào)用Index類的test2方法時該代碼有效,$event為字符串hello var_dump($event); //當(dāng)調(diào)用Index類的test3方法時該代碼有效,$event為Index類的實例 //可以訪問Index類的name變量 echo $event->name; //當(dāng)調(diào)用Index類的test4方法時該代碼有效,$event為Other類的實例 //可以調(diào)用Other類的hello方法 echo $event->hello(); } }
二、通過訂閱
1、創(chuàng)建訂閱類
在命令行模式下進(jìn)入框架根目錄執(zhí)行
php think make:subscribe <自定義的類名>
例如:
php think make:subscribe UserSubscribe
執(zhí)行之后將在<框架根目錄>\app\subscribe\下生成UserSubscribe這個類。
2、配置監(jiān)聽
在<框架根目錄>\app\event.php這個文件的subscribe數(shù)組中配置UserSubscribe這個類,如下:
'subscribe' => ['app\subscribe\UserSubscribe'],
注意:為了測試效果,要把上面配置的UserListener從listen數(shù)組刪除掉
3、觸發(fā)監(jiān)聽
跟第一種途徑一樣
4、處理監(jiān)聽邏輯
處理監(jiān)聽的邏輯又有兩種方法,我稱之為自動綁定和手動綁定。手動綁定和自動綁定是互斥的,只能二選一。
4.1 自動綁定
在UserSubscribe類中添加ontestEvent方法,在該方法中完成業(yè)務(wù)邏輯。添加的方法名不能隨意定義,規(guī)則是事件名稱前面加上on。因為我們在event.php里定義的事件名稱是testEvent,所以方法名就是ontestEvent(注意大小寫)。監(jiān)聽方法定義之后就自動與事件綁定,所以我稱之為自動綁定。
完整代碼如下
Other和Index類的代碼跟第一種途徑一樣
UserSubscribe:事件訂閱類
<?php namespace app\subscribe; class UserSubscribe { public function ontestEvent($user) { //當(dāng)調(diào)用Index類的test1方法時該代碼有效,$event為null var_dump($user); //當(dāng)調(diào)用Index類的test2方法時該代碼有效,$event為字符串hello var_dump($user); //當(dāng)調(diào)用Index類的test3方法時該代碼有效,$event為Index類的實例 //可以訪問Index類的name變量 echo $user->name; //當(dāng)調(diào)用Index類的test4方法時該代碼有效,$event為Other類的實例 //可以調(diào)用Other類的hello方法 echo $user->hello(); } }
4.2 手動綁定
首先,創(chuàng)建事件類,負(fù)責(zé)處理具體的業(yè)務(wù)邏輯。在命令行模式下進(jìn)入框架根目錄執(zhí)行:
php think make:event <自定義的類名>
例如:
php think make:event UserEvent
執(zhí)行之后將在<框架根目錄>\app\event\下生成UserEvent這個類。
再在該類中定義一個handle方法,該方法有一個傳入?yún)?shù)。方法名和傳入的參數(shù)名可以任意定義。具體的業(yè)務(wù)邏輯就可以放在handle方法里面處理。
然后,在UserSubscribe類中添加subscribe方法,該方法傳入?yún)?shù)為 Event 對象。然后在該方法中將監(jiān)聽的事件綁定到UserEvent類的handle方法上。如下:
$event->listen('testEvent', [app('app\event\UserEvent'), 'handle']);
完整代碼如下
Other和Index類的代碼跟第一種途徑一樣
UserSubscribe:事件訂閱類
<?php declare (strict_types = 1); namespace app\subscribe; use think\Event; class UserSubscribe { public function subscribe(Event $event) { $event->listen('testEvent', [app('app\event\UserEvent'), 'handle']); } }
UserEvent:事件處理類
<?php declare (strict_types = 1); namespace app\event; class UserEvent { public function handle($user) { //當(dāng)調(diào)用Index類的test1方法時該代碼有效,$user為null var_dump($user); //當(dāng)調(diào)用Index類的test2方法時該代碼有效,$user為字符串hello var_dump($user); //當(dāng)調(diào)用Index類的test3方法時該代碼有效,$user為Index類的實例 //可以訪問Index類的name變量 echo $user->name; //當(dāng)調(diào)用Index類的test4方法時該代碼有效,$user為Other類的實例 //可以調(diào)用Other類的hello方法 echo $user->hello(); } }
總結(jié)
1、通過監(jiān)聽的方式,每個事件都需要定義一個監(jiān)聽類來處理監(jiān)聽邏輯,并且在event.php的listen數(shù)組中配置
2、通過訂閱的方式,如果采用自動綁定,則需要在訂閱類中為每個事件定義一個監(jiān)聽方法(方法名不能自己定義),不需要定義subscribe方法;如果采用手動綁定,則定義subscribe方法,并為每一個事件綁定負(fù)責(zé)處理業(yè)務(wù)邏輯的具體方法(方法名可以自己定義)
3、通過監(jiān)聽的方式中,事件類基本上可有可無,因為創(chuàng)建的監(jiān)聽類本來就是專門處理對應(yīng)的事件的業(yè)務(wù)邏輯的。并且監(jiān)聽類可以用事件類代替。
4、通過訂閱的方式中,如果采用自動綁定,事件類也沒有必要,因為在訂閱類中為每個事件定義的監(jiān)聽方法本來就是專門處理對應(yīng)的事件的業(yè)務(wù)邏輯的。如果采用手動綁定,也可以把監(jiān)聽方法寫在訂閱類中,那么事件類也就沒必要了。但是個人認(rèn)為手動綁定還是使用事件類比較好。訂閱類只負(fù)責(zé)綁定,事件類負(fù)責(zé)處理具體業(yè)務(wù)邏輯,這樣結(jié)構(gòu)上比較清晰
5、其實通過監(jiān)聽的方式中,監(jiān)聽類(例子中的UserListener)可以替換成其他命名空間下的其他類,只要該類有一個handle方法就行,比如事件類。替換之后記得要在event.php配置文件中做對應(yīng)修改。同理,通過訂閱的方式中,也可以將訂閱類(例子中的UserSubscribe)直接替換為其他類,但是要記得自動綁定需要在該類下有符合命名規(guī)則的方法,手動綁定需要在該類下有一個subscribe方法
以上就是Thinkphp事件機(jī)制兩種實現(xiàn)方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Thinkphp事件機(jī)制的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PHP自帶函數(shù)給數(shù)字或字符串自動補齊位數(shù)
很多時候我們需要對數(shù)字進(jìn)行格式化,比如位數(shù)不足前面加0補足。用 php可以很輕易實現(xiàn),因為PHP自帶了相關(guān)功能的函數(shù)。2014-07-07php版本的cron定時任務(wù)執(zhí)行器使用實例
這篇文章主要介紹了php版本的cron定時任務(wù)執(zhí)行器使用實例,是非常實用的一個功能,需要的朋友可以參考下2014-08-08php實現(xiàn)xml數(shù)據(jù)轉(zhuǎn)數(shù)組兩種方式
這篇文章主要為大家詳細(xì)介紹了php實現(xiàn)xml數(shù)據(jù)轉(zhuǎn)數(shù)組兩種方式的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的小伙伴可以參考下2023-11-11Thinkphp框架安裝composer擴(kuò)展包流程梳理
這篇文章主要介紹了Thinkphp使用composer安裝擴(kuò)展包教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09