學了兩年半,Yii2的內置事件知多少?

書接上回,我將代碼提交到服務器後被小X經理一頓批,她是這樣說的。php

小X: 你丫不知道yii2本身就有登錄後的事件麼?
我:不知道啊,咋的吧?
小X:改!????,而後統計個yii2預約義事件表給我。
我:哦,好的。???

好吧,算咱技術不到家,那就趕忙改吧,先回顧下上一篇我都幹了啥,我是在會員登錄後觸發了一個事件,既然說有內置的,那就找找吧。html

我知道登錄功能是使用yiiwebUser這個類,那應該去那裏去找它們。它在@app/vendor/yiisoft/yii2/web/User.phpgit

5分鐘之後~

果真,我找到了那個事件,還用了3分鐘分析瞭如何使用,如今把個人研究成果和你們分享下。web

對於yii2系統的登錄,yiiwebUser類一共提供了4個事件,以下服務器

const EVENT_BEFORE_LOGIN = 'beforeLogin';
const EVENT_AFTER_LOGIN = 'afterLogin';
const EVENT_BEFORE_LOGOUT = 'beforeLogout';
const EVENT_AFTER_LOGOUT = 'afterLogout';

分別是登錄先後、註銷先後,我要使用的是EVENT_AFTER_LOGIN事件,那麼如何去使用那?yii2

既然是登錄,仍是先看下yiiwebUser中的login方法,看看是否有蛛絲馬跡cookie

public function login(IdentityInterface $identity, $duration = 0){

    if ($this->beforeLogin($identity, false, $duration)) {
        $this->switchIdentity($identity, $duration);
        $id = $identity->getId();
        $ip = Yii::$app->getRequest()->getUserIP();
        if ($this->enableSession) {
            $log = "User '$id' logged in from $ip with duration $duration.";
        } else {
            $log = "User '$id' logged in from $ip. Session not enabled.";
        }
        Yii::info($log, __METHOD__);
        $this->afterLogin($identity, false, $duration);
    }

    return !$this->getIsGuest();
}

我看到了 $this->afterLogin($identity, false, $duration),彷佛這個方法是登錄後作了一些事情,那就繼續看吧app

protected function afterLogin($identity, $cookieBased, $duration){

    $this->trigger(self::EVENT_AFTER_LOGIN, new UserEvent([
        'identity' => $identity,
        'cookieBased' => $cookieBased,
        'duration' => $duration,
    ]));
}

OMG,真的發現了,原來這個方法觸發了EVENT_AFTER_LOGIN事件,而且還很貼心的將identity等信息傳遞給了綁定EVENT_AFTER_LOGIN事件的每一位觀察者。yii

因而思路來了㊙️㊙️㊙️㊙️㊙️㊙️ide

我只須要在login前綁定EVENT_AFTER_LOGIN事件,而後afterLogin會自動觸發全部訂閱者。

重構開始

use yii\web\User;
class UserController extends Controller {
    
    public function __construct(){
        //    綁定事件
        $this->on(User::EVENT_AFTER_LOGIN,['app\models\OLog','add']); 
        $this->on(User::EVENT_AFTER_LOGIN,['app\models\Admin','sendMail']); 
        $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); 
    }
    
    public function actionIndex(){
        .....
        //    login                
    }
}

我以前定義的EVENT_USER_LOGIN天然能夠刪除了,上面看到afterLogin方法觸發事件的時候已經傳遞了一個UserEvent,裏面含有登錄的詳細信息了,我上一篇本身定義的那個UserLoginEvent也就能夠刪除了。

使用系統自帶的事件,真心省了太多代碼了,感謝yii2開發團隊,感謝大家八倍祖主。

對於登錄主題就重構完了,如今我還須要改下訂閱者的代碼,畢竟傳遞給訂閱者的$event不同了,拿一個訂閱者舉例吧

// User app\models\User.php
class User {
    static public function notifyFirend($event){
        $userId = $event->userId;
        echo "告訴了朋友們我登錄了";
    }
}

我要對其進行小手術,diu一下,手術後的樣子以下

// User app\models\User.php
class User {
    static public function notifyFirend($event){
        $userId = $event->identity->id;
        echo "告訴了朋友們我登錄了";
    }
}

ok~
到此爲止咱們對登錄邏輯的事件處理就完成了,去掉了自定義的事件,綁定了 User::EVENT_AFTER_LOGIN 內置事件。

還沒完~

是的還沒完,小X經理還讓我提交一個yii2預約義事件表給她,我深入體會到這個表格的重要性,有了它,即可以通曉yii全部事件,正所謂就算成功,也不必定自宮。

可是,yii2這麼大,我如何一個不落的獲得它們那?

看來要藉助於咱們的神器PHPSTORM了。

首先咱們知道yii2對於事件名的命名規則,常量大寫、觀察下發現內置的這些事件都是EVENT_開頭的,有了這些特徵,那開始吧。

方法以下:咱們對vendor/yiisoft目錄進行查找(find in path),找到全部const EVENT_開頭的行。

alt

是的,一共有41個。最近據說有個叫阿北的人作了一個yii速查表,我計劃將這個表格分享給他也。

yii2速查表之event內置一覽表 http://nai8.me/tool-sc.html

建議你背下這些事件,至少在作事件的時候查一遍速查表,能用系統的優先使用系統的。

學到了一些

很高興完成了小x經理關於登錄事件的需求,經過這些讓我對yii的事件有了一個大致瞭解,知道了事件是觀察者模式的一種實現、知道yii2內置了不少事件,咱們應該優先使用它們。

begin git。

一陣QQ震動,帶着壞笑的小x經理髮了一句消息給我:「來,小北同窗!」

天,又咋了,下篇告訴你。

相關文章
相關標籤/搜索