文档章节

学了两年半,Yii2的内置事件知多少?

阿北2017
 阿北2017
发布于 2017/05/23 00:02
字数 1195
阅读 563
收藏 16

书接上回,我将代码提交到服务器后被小X经理一顿批,她是这样说的。

小X: 你丫不知道yii2自己就有登陆后的事件么?
我:不知道啊,咋的吧?
小X:改!😡😡😡😡,然后统计个yii2预定义事件表给我。
我:哦,好的。😱😱😱

好吧,算咱技术不到家,那就赶紧改吧,先回顾下上一篇我都干了啥,我是在会员登陆后触发了一个事件,既然说有内置的,那就找找吧。

我知道登陆功能是使用yii\web\User这个类,那应该去那里去找它们。它在@app/vendor/yiisoft/yii2/web/User.php

@@nai8@@

5分钟以后~

果然,我找到了那个事件,还用了3分钟分析了如何使用,现在把我的研究成果和大家分享下。

对于yii2系统的登陆,yii\web\User类一共提供了4个事件,如下

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

分别是登陆前后、注销前后,我要使用的是EVENT_AFTER_LOGIN事件,那么如何去使用那?

既然是登陆,还是先看下yii\web\User中的login方法,看看是否有蛛丝马迹

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),似乎这个方法是登陆后做了一些事情,那就继续看吧

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事件的每一位观察者。

于是思路来了㊙️㊙️㊙️㊙️㊙️㊙️

我只需要在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经理发了一句消息给我:“来,小北同学!”

天,又咋了,下篇告诉你。 输入图片说明

© 著作权归作者所有

共有 人打赏支持
阿北2017
粉丝 61
博文 54
码字总数 68986
作品 0
洛阳
加载中

评论(2)

阿北2017
阿北2017

引用来自“落雪无声”的评论

你有一个好的老板啊。

回复@落雪无声 : 恩,是哈。
落雪无声
落雪无声
你有一个好的老板啊。
Yii 2 公共预览版发布

我们非常高兴宣布 Yii 2 公共预览版发布,地址在 GItHub,这是Yii2在开始开发到两年多的重写的一个里程碑。 注意:Yii2还正处于开发阶段,可能会在不通知的情况下引入较大的修改,所以不要在...

首席烤地瓜
2013/05/04
2.6K
15
从配置文件的角度去了解Yii2

前言 Yii2是一个奇特的框架,其牺牲了现在盛行的解耦设计,用一个高度耦合的结构提供给开发者一个方便的几类抽象,Application,Module,Component,甚至是ServiceLocator.想让对象具备哪类特征就直...

Vett
2017/12/23
0
0
Yii2 实例管理

Yii2 实例管理 Yii2框架没有提供类似ZendFramework3中提供的ServiceManager.那么Yii2框架是如何管理对象实例的呢? 长时间使用Yii2框架的童鞋一定已经适应了对象中的public变量,以及一个来自y...

Vett
2017/12/23
0
0
这些最热门的 PHP 框架,哪一款是你的菜?

原文出处:opensource 译文出处:开源中国—两味真火 PHP 是世界上最流行的编程语言之一,广泛用于主要的项目中。例如,Facebook 就是利用 PHP 来创建和维护他们的内部系统;WordPress 内部基...

opensource
2016/12/27
0
0
yii2 - Behavior 实例及源码分析

Behavior 的简述 行为简单来说是组件的扩展,可以对组件的属性,方法,事件 (yii2组件的三大要点)进行扩展而无需改动组件现有的代码逻辑。即此行为所拥有的属性,方法,事件,都会被绑定它...

big_cat
2016/06/01
811
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Ubuntu18.04 显卡GF-940MX安装NVIDIA-390.77

解决办法: 下面就给大家一个正确的姿势在Ubuntu上安装Nvidia驱动: (a)首先去N卡官网下载自己显卡对应的驱动:www.geforce.cn/drivers (b)下载后好放在英文路径的目录下,怎么简单怎么来...

AI_SKI
今天
0
0
深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
今天
0
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
今天
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
2
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部