书接上回,我将代码提交到服务器后被小X经理一顿批,她是这样说的。php
小X: 你丫不知道yii2本身就有登录后的事件么? 我:不知道啊,咋的吧? 小X:改!????,而后统计个yii2预约义事件表给我。 我:哦,好的。???
好吧,算咱技术不到家,那就赶忙改吧,先回顾下上一篇我都干了啥,我是在会员登录后触发了一个事件,既然说有内置的,那就找找吧。html
我知道登录功能是使用yiiwebUser这个类,那应该去那里去找它们。它在@app/vendor/yiisoft/yii2/web/User.phpgit
果真,我找到了那个事件,还用了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_开头的行。
是的,一共有41个。最近据说有个叫阿北的人作了一个yii速查表,我计划将这个表格分享给他也。
yii2速查表之event内置一览表 http://nai8.me/tool-sc.html
建议你背下这些事件,至少在作事件的时候查一遍速查表,能用系统的优先使用系统的。
很高兴完成了小x经理关于登录事件的需求,经过这些让我对yii的事件有了一个大致了解,知道了事件是观察者模式的一种实现、知道yii2内置了不少事件,咱们应该优先使用它们。
begin git。
一阵QQ震动,带着坏笑的小x经理发了一句消息给我:“来,小北同窗!”
天,又咋了,下篇告诉你。