thinkphp6事件監聽event-listene

yiqiu發表於2022-04-15

 

事件系統可以看成是行為系統的升級版,相比行為系統強大的地方在於事件本身可以是一個類,並且可以更好的支援事件訂閱者。

事件相比較中介軟體的優勢是事件比中介軟體更加精準定位(或者說粒度更細),並且更適合一些業務場景的擴充套件。例如,我們通常會遇到使用者註冊或者登入後需要做一系列操作,通過事件系統可以做到不侵入原有程式碼完成登入的操作擴充套件,降低系統的耦合性的同時,也降低了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

首發地址:http://upwqy.com/?p=405

 

相關文章