溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ThinkPHP6.0中事件系統(tǒng)以及查詢事件、模型事件的使用示例

發(fā)布時(shí)間:2021-01-16 10:20:32 來(lái)源:億速云 閱讀:410 作者:小新 欄目:編程語(yǔ)言

小編給大家分享一下ThinkPHP6.0中事件系統(tǒng)以及查詢事件、模型事件的使用示例,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

在最新的6.0版本中引入了新的事件系統(tǒng)用以替代5.1版本的行為,同時(shí)也接管了數(shù)據(jù)庫(kù)事件和模型事件。

定義事件

事件系統(tǒng)的所有操作都通過(guò)think\facade\Event類進(jìn)行靜態(tài)調(diào)用

事件系統(tǒng)使用了觀察者模式,提供了解耦應(yīng)用的更好方式。在你需要監(jiān)聽(tīng)事件的位置,添加如下代碼:

Event::trigger('UserLogin');

或者使用助手函數(shù)

event('UserLogin');

這里UserLogin表示一個(gè)事件標(biāo)識(shí),如果你定義了單獨(dú)的事件類,你可以使用事件類名,甚至可以傳入一個(gè)事件類實(shí)例。

event('app\event\UserLogin');

事件類可以通過(guò)命令行快速生成

php think make:event UserLogin

默認(rèn)會(huì)生成一個(gè)app\event\UserLogin事件類,也可以指定完整類名生成。

我們可以給事件類添加方法

namespace app\event;
use app\model\User;
class UserLogin
{
    public $user;
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

一般事件類無(wú)需繼承任何其它類。

你可以給事件類綁定一個(gè)事件標(biāo)識(shí)

Event::bind('UserLogin', 'app\event\UserLogin');

或者在應(yīng)用的event.php事件定義文件中批量綁定。

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件綁定
    ],
];

如果你沒(méi)有定義事件類的話,則無(wú)需綁定。

ThinkPHP的事件系統(tǒng)不依賴事件類,如果沒(méi)有額外的需求,僅通過(guò)事件標(biāo)識(shí)也可以使用。

你可以在event方法中傳入一個(gè)事件參數(shù)

event('UserLogin', $user);

事件監(jiān)聽(tīng)

你可以手動(dòng)注冊(cè)一個(gè)事件監(jiān)聽(tīng)

Event::listen('UserLogin', function($user) {
    // 
});

或者使用監(jiān)聽(tīng)類

Event::listen('UserLogin', 'app\listener\UserLogin');

可以通過(guò)命令行快速生成一個(gè)事件監(jiān)聽(tīng)類

php think make:listener UserLogin

默認(rèn)會(huì)生成一個(gè)app\listener\UserLogin事件監(jiān)聽(tīng)類,也可以指定完整類名生成。

事件監(jiān)聽(tīng)類只需要定義一個(gè)handler方法,支持依賴注入。

<?php
namespace app\listener;
class UserLogin
{
    public function handle($user)
    {
        // 事件監(jiān)聽(tīng)處理
    }   
}

在handler方法中如果返回了false,則表示監(jiān)聽(tīng)中止,將不再執(zhí)行該事件后面的監(jiān)聽(tīng)。

一般建議直接在事件定義文件中定義對(duì)應(yīng)事件的監(jiān)聽(tīng)。

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件綁定
    ],
    'listen'  =>    [
        'UserLogin'    =>    ['\app\listener\UserLogin'],
        // 更多事件監(jiān)聽(tīng)
    ],
];

事件訂閱

可以通過(guò)事件訂閱機(jī)制,在一個(gè)監(jiān)聽(tīng)器中監(jiān)聽(tīng)多個(gè)事件,例如通過(guò)命令行生成一個(gè)事件訂閱者類,

php think make:subscribe User

默認(rèn)會(huì)生成app\subscribe\User類,或者你可以指定完整類名生成。

然后你可以在事件訂閱類中添加不同事件的監(jiān)聽(tīng)方法,例如:

<?php
namespace app\subscribe;
class User
{
    public function onUserLogin($user)
    {
        // 事件響應(yīng)處理
    }
    public function onUserLogout($user)
    {
        // 事件響應(yīng)處理
    }
}

監(jiān)聽(tīng)事件的方法命名規(guī)范是on+事件標(biāo)識(shí)(駝峰命名),然后注冊(cè)該事件訂閱

Event::subscribe('app\subscribe\User');

一般建議直接在事件定義文件中定義

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件綁定
    ],
    'listen'  =>    [
        'UserLogin'    =>    ['\app\listener\UserLogin'],
        // 更多事件監(jiān)聽(tīng)
    ],
    'subscribe'    =>    [
       '\app\subscribe\User',
        // 更多事件訂閱
    ],
];

內(nèi)置事件

內(nèi)置的系統(tǒng)事件包括:

ThinkPHP6.0中事件系統(tǒng)以及查詢事件、模型事件的使用示例

AppInit事件定義必須在全局事件定義文件中定義,其它事件支持在應(yīng)用的事件定義文件中定義。

原來(lái)5.1的一些行為標(biāo)簽已經(jīng)廢棄,所有取消的標(biāo)簽都可以使用中間件更好的替代??梢园阎虚g件看成處理請(qǐng)求以及響應(yīng)輸出相關(guān)的特殊事件。事實(shí)上,中間件的handle方法只是具有特殊的參數(shù)以及返回值而已。

查詢事件

數(shù)據(jù)庫(kù)操作的回調(diào)也稱為查詢事件,是針對(duì)數(shù)據(jù)庫(kù)的CURD操作而設(shè)計(jì)的回調(diào)方法,主要包括:

ThinkPHP6.0中事件系統(tǒng)以及查詢事件、模型事件的使用示例

使用下面的方法注冊(cè)數(shù)據(jù)庫(kù)查詢事件

\think\facade\Db::event('before_select', function ($query) {
    // 事件處理
    return $result;
});

同一個(gè)查詢事件可以注冊(cè)多個(gè)響應(yīng)執(zhí)行。查詢事件在新版里面也已經(jīng)被事件系統(tǒng)接管了,因此如果你注冊(cè)了一個(gè)before_select查詢事件監(jiān)聽(tīng),底層其實(shí)是向標(biāo)識(shí)為db.before_select的事件注冊(cè)了一個(gè)監(jiān)聽(tīng)。

查詢事件的方法參數(shù)只有一個(gè):當(dāng)前的查詢對(duì)象。但你可以通過(guò)依賴注入的方式添加額外的參數(shù)。

模型事件

模型事件是指在進(jìn)行模型的查詢和寫(xiě)入操作的時(shí)候觸發(fā)的操作行為。

模型事件只在調(diào)用模型的方法生效,使用查詢構(gòu)造器操作是無(wú)效的。

模型支持如下事件:

ThinkPHP6.0中事件系統(tǒng)以及查詢事件、模型事件的使用示例

注冊(cè)的回調(diào)方法支持傳入一個(gè)參數(shù)(當(dāng)前的模型對(duì)象實(shí)例),但支持依賴注入的方式增加額外參數(shù)。

如果before_write、before_insert、 before_update 、before_delete事件方法中返回false或者拋出think\exception\

ModelEventException異常的話,則不會(huì)繼續(xù)執(zhí)行后續(xù)的操作。

模型事件定義

最簡(jiǎn)單的方式是在模型類里面定義靜態(tài)方法來(lái)定義模型的相關(guān)事件響應(yīng)。

<?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);
    }
}

參數(shù)是當(dāng)前的模型對(duì)象實(shí)例,支持使用依賴注入傳入更多的參數(shù)。

模型事件觀察者

如果希望模型的事件單獨(dú)管理,可以給模型注冊(cè)一個(gè)事件觀察者,例如:

<?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);
    }
}

觀察者類的事件響應(yīng)方法的第一個(gè)參數(shù)就是模型對(duì)象實(shí)例,你依然可以通過(guò)依賴注入傳入其它的對(duì)象參數(shù)。

以上是“ThinkPHP6.0中事件系統(tǒng)以及查詢事件、模型事件的使用示例”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI