接上回,上次的更改小x經理很滿意,可是提出了幾點意見。php
她是這樣說的:前端
系統本地留log不必弄個類,太麻煩了,日誌也不須要記錄具體人,有個時間便可。git
管理員就一我的,不要用靜態方法。程序員
經理必定是處女座的,好吧,她的要求是對的,每一個事件都是具備本身的用意,有的是一個對象,有的是系統級別,有的是一類東東,看來我要先複習一下yii的事件都能綁定什麼了?web
前面說過yii一共能綁定四種類型的函數,分別是app
全局函數yii
類的靜態函數函數
對象的方法this
匿名函數日誌
支持的函數理解很簡單,難在使用場景,這是咱們要思考的。
@@nai8@@
針對小x經理說的第一個問題,我彷佛用一個匿名函數就能夠搞定了,因而我改了appcontrollersUserController.php 中對於OLog的綁定邏輯
use yii\web\User; class UserController extends Controller { public function __construct(){ // 綁定事件 $this->on(User::EVENT_AFTER_LOGIN,function($event){ $time = date("Y-m-d H:i:s"); Yii::info("有人在{$time}登錄了"); }); $this->on(User::EVENT_AFTER_LOGIN,['app\models\Admin','sendMail']); $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); } public function actionIndex(){ ..... // login } }
而對於小x經理的第二個需求,當有人登錄後將一個郵件發給一個管理員,那麼應該是Admin實例化後的一個方法,看來此次我要改造Amdin觀察者類了
開始改造
// Admin app\models\Admin.php class Admin { public function sendMail($event){ echo "我給管理員發了郵件"; } }
我將sendMail的靜態化去掉了,而後修改綁定的函數類型
use yii\web\User; class UserController extends Controller { public function __construct(){ // 綁定事件 $this->on(User::EVENT_AFTER_LOGIN,function($event){ $time = date("Y-m-d H:i:s"); Yii::info("有人在{$time}登錄了"); }); $admin = Admin::findOne(1); //管理員id爲1 $this->on(User::EVENT_AFTER_LOGIN,[$admin,'sendMail']); $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); } public function actionIndex(){ ..... // login } }
接下來我準備提交本次小x給的任務,在提交前咱們作一點事情,都知道on叫作綁定,trigger叫觸發,那麼上面這些訂閱者的事件函數,咱們給它們起個名字叫作 「事件處理器」,之後會用這個名字表明它們。
我是時間分隔線⛔️⛔️⛔️⛔️⛔️⛔️
10分鐘後我回到了本身的位置,小x經理對本次修改很滿意,可是她給了我另外一個活,原話是這樣:
小北啊,看來你對事件蠻有悟性的,我再給你一個事件的任務,幫你提升啊
個人心呀~拔涼拔涼的~
此次的任務以下:
晚24點到次日6點,記錄系統log,不要給客戶和管理員發消息,客戶要覺覺、管理員要覺覺。
政府說要監聽每次登錄,上面的判斷對政府監聽不起做用,煩死它們。
對於政府的監聽一直放到最前面,不受後續新增事件處理器影響,也不受未來程序員有可能勿調on代碼順序所影響。
聽着很複雜,偶心中竊喜,yii已經提供了功能,我知道對於一個事件有多個事件處理器的時候,事件處理器執行的順序和綁定順序一致,而且yii提供了一個阻斷機制,你能夠對一個事件處理器執行阻斷後,後面的全部事件處理器都不會再執行。
這個阻斷機制就是event對象的handled,默認爲假,不阻斷。開始寫代碼
use yii\web\User; class UserController extends Controller { public function __construct(){ // 綁定事件 $this->on(User::EVENT_AFTER_LOGIN,function($event){ $time = date("Y-m-d H:i:s"); Yii::info("有人在{$time}登錄了"); if(時間在晚24點和次日6點間){ $event->handled = true; } }); $admin = Admin::findOne(1); //管理員id爲1 $this->on(User::EVENT_AFTER_LOGIN,[$admin,'sendMail']); $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); } public function actionIndex(){ ..... // login } }
你看到了把,就是一句簡單的 $event->handled = true;就ok了。
接下來咱們要添加政府訂閱者,咱們編寫了一個叫作Gov的訂閱者類,它有一個叫作notify的事件處理器,而且要讓他的優先級最高。
上面咱們說到了事件處理器執行的順序和on綁定順序一致,一種方法是將Gov的綁定放到綁定列表最前面,可是這樣又不知足小x經理的第三條交代,好在yii已經有該功能了。
對於綁定函數on,存在着第四個參數,當你設置該參數爲flase時,此事件處理器將進入處處理器列表最前端,開始幹
use yii\web\User; class UserController extends Controller { public function __construct(){ // 綁定事件 $this->on(User::EVENT_AFTER_LOGIN,function($event){ $time = date("Y-m-d H:i:s"); Yii::info("有人在{$time}登錄了"); if(時間在晚24點和次日6點間){ $event->handled = true; } }); $admin = Admin::findOne(1); //管理員id爲1 $this->on(User::EVENT_AFTER_LOGIN,[$admin,'sendMail']); $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); $this->on(User::EVENT_AFTER_LOGIN,['app\models\Gov','notify'],null,false); } public function actionIndex(){ ..... // login } }
這樣一設置,由於它處於第一位,時間範圍限制不了它,之後增長的其餘事件處理器,只要我保證他們的第四個參數都不是flase,則Gov永遠是第一位。
ok,阻斷後續事件處理器的執行、人爲影響事件處理器的執行順序,我用這兩個知識點解決了小x經理的需求。
開始 git
你覺得這就完事了?尚未,下回告訴你git後的故事。
更多能夠來個人yii原創視頻小站 http://nai8.me