在最新的6.0版本中引入了新的事件系統以取代5.1版本的行為,同時也接管了資料庫事件和模型事件。
本篇主要描述下新版的事件系統以及查詢事件、模型事件的使用。
定義事件
事件系統的所有操作都透過think\facade\Event類別進行靜態呼叫
事件系統使用了觀察者模式,提供了解耦應用的更好方式。在你需要監聽事件的位置,加入如下程式碼:
Event::trigger('UserLogin');
或使用助手函數
event('UserLogin');
這裡UserLogin表示一個事件標識,如果你定義了單獨的事件類,你可以使用事件類別名,甚至可以傳入一個事件類別實例。
event('app\event\UserLogin');
事件類可以透過命令列快速產生
php think make:event UserLogin
預設會產生一個app\event\UserLogin事件類,也可以指定完整類名產生。
我們可以為事件類別新增方法
namespace app\event; use app\model\User; class UserLogin { public $user; public function __construct(User $user) { $this->user = $user; } }
一般事件類別無需繼承任何其它類別。
你可以給事件類別綁定一個事件標識
Event::bind('UserLogin', 'app\event\UserLogin');
或是在套用的event.php事件定義檔中批次綁定。
return [ 'bind' => [ 'UserLogin' => 'app\event\UserLogin', // 更多事件绑定 ], ];
如果你沒有定義事件類別的話,則無需綁定。
ThinkPHP的事件系統不依賴事件類,如果沒有額外的需求,僅透過事件標識也可以使用。
你可以在event方法中傳入一個事件參數
event('UserLogin', $user);
事件監聽
你可以手動註冊一個事件監聽
Event::listen('UserLogin', function($user) { // });
或使用監聽類
Event::listen('UserLogin', 'app\listener\UserLogin');
可以透過命令列快速產生一個事件監聽類
php think make:listener UserLogin
預設會產生一個app\listener\UserLogin事件監聽類,也可以指定完整類名生成。
事件監聽類別只需要定義一個handler方法,支援依賴注入。
<?php namespace app\listener; class UserLogin { public function handle($user) { // 事件监听处理 } }
在handler方法中如果傳回了false,則表示監聽中止,將不再執行該事件後面的監聽。
一般建議直接在事件定義檔中定義對應事件的監聽。
return [ 'bind' => [ 'UserLogin' => 'app\event\UserLogin', // 更多事件绑定 ], 'listen' => [ 'UserLogin' => ['\app\listener\UserLogin'], // 更多事件监听 ], ];
事件訂閱
可以透過事件訂閱機制,在一個監聽器中監聽多個事件,例如透過命令列產生一個事件訂閱者類,
php think make:subscribe User
預設會產生app\subscribe\User類,或者你可以指定完整類名生成。
然後你可以在事件訂閱類別中新增不同事件的監聽方法,例如:
<?php namespace app\subscribe; class User { public function onUserLogin($user) { // 事件响应处理 } public function onUserLogout($user) { // 事件响应处理 } }
監聽事件的方法命名規格是on 事件標識(駝峰命名),然後註冊該事件訂閱
Event::subscribe('app\subscribe\User');
一般建議直接在事件定義檔中定義
return [ 'bind' => [ 'UserLogin' => 'app\event\UserLogin', // 更多事件绑定 ], 'listen' => [ 'UserLogin' => ['\app\listener\UserLogin'], // 更多事件监听 ], 'subscribe' => [ '\app\subscribe\User', // 更多事件订阅 ], ];
內建事件
內建的系統事件包括:
##AppInit事件定義必須在全域事件定義檔中定義,其它事件支援在應用程式的事件定義檔中定義。原來5.1的一些行為標籤已經廢棄,所有取消的標籤都可以使用中間件更好的替代品。可以把中間件看成處理請求以及回應輸出相關的特殊事件。事實上,中間件的handle方法只是具有特殊的參數以及回傳值而已。
查詢事件
資料庫操作的回呼也稱為查詢事件,是針對資料庫的CURD操作而設計的回呼方法,主要包括:使用下面的方法註冊資料庫查詢事件\think\facade\Db::event('before_select', function ($query) { // 事件处理 return $result; });
查詢事件的方法參數只有一個:目前的查詢物件。但你可以透過依賴注入的方式來添加額外的參數。
模型事件
模型事件是指在進行模型的查詢和寫入操作的時候觸發的操作行為。模型事件只在呼叫模型的方法生效,使用查詢建構器操作是無效的。模型支援如下事件:註冊的回呼方法支援傳入一個參數(目前的模型物件實例),但支援依賴注入的方式增加額外參數。
如果before_write、before_insert、 before_update 、before_delete事件方法中回傳false或拋出think\exception\ModelEventException异常的话,则不会继续执行后续的操作。
模型事件定义
最简单的方式是在模型类里面定义静态方法来定义模型的相关事件响应。
<?php namespace app\index\model; use think\Model; use app\index\model\Profile; class User extends Model { public static function onBeforeUpdate($user) { if ('thinkphp' == $user->name) { return false; } } public static function onAfterDelete($user) { Profile::destroy($user->id); } }
参数是当前的模型对象实例,支持使用依赖注入传入更多的参数。
模型事件观察者
如果希望模型的事件单独管理,可以给模型注册一个事件观察者,例如:
<?php namespace app\index\model; use think\Model; class User extends Model { protected $observerClass = 'app\index\observer\User'; }
User观察者类定义如下:
<?php namespace app\index\observer; use app\index\model\Profile; class User { public function onBeforeUpdate($user) { if ('thinkphp' == $user->name) { return false; } } public function onAfterDelete($user) { Profile::destroy($user->id); } }
观察者类的事件响应方法的第一个参数就是模型对象实例,你依然可以通过依赖注入传入其它的对象参数。
PHP中文网,大量的免费ThinkPHP入门教程,欢迎在线学习!
本文转自:https://blog.thinkphp.cn/1037387
以上是ThinkPHP6.0:事件系統以及查詢事件、模型事件的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!