yii2-事件 系列 第一篇
博主使用yii2时间不长,用于备忘分享,若有不正之处欢迎指正。十分感谢。
本文仅用于快速使用yii2事件。后续文章将详细介绍yii2事件的更多细节。
前言
最近在使用框架做项目中,多次使用到了Behavior。
但是在使用的时候,切记不要盲目使用behavior,而是要区分场景。明白了场景到底需要什么的时候,再去选择使用事件(event),还是行为(behavior)。
使用事件,可以在特定的时点,触发执行预先设定的一段代码,事件既是代码解耦的一种方式,也是设计业务流程的一种模式。现代软件中,事件无处不在,比如,你发了个微博,触发了一个事件,导致关注你的人,看到了你新发出来的内容。对于事件而言,有这么几个要素 [1]:
yii2事件方法
Event文件( \yii\base\Event )函数模型:
1 | class Event extends Object |
on =>绑定事件handler
一个最简单的绑定:
1
2
3
4
5
6
7
8
9
\yii\base\Event::on(
BaseActiveRecord::className(),//需要绑定的类名
BaseActiveRecord::EVENT_BEFORE_INSERT,//绑定插入前事件
function ($event){//事件handler。这里的$event即是上面类中的Event。
echo 'I will insert a record into database';
//...
}
);以上例子表示将AR数据库插入之前事件,与自定义handler函数绑定。
off =>解绑事件handler
一个最简单的解除绑定:
1
2
3
4
5
6
\yii\base\Event::off(
BaseActiveRecord::className(),//要接触绑定的类名
BaseActiveRecord::EVENT_AFTER_DELETE,//解除绑定的事件
//如果不写第三个参数,默认为null,将移除事件所有的handler。
);以上例子表示移除AR数据被删除后事件绑定的所有的handler.该函数将返回True或False表示是否找到并移除了该handler。
hasHandlers =>判断这个类以及其父类的指定事件是否具有handler。
一个最简单的判断:
1
2
3
4
5
\yii\base\Event::hasHandlers(
BaseActiveRecord::className(),//要判断的类
BaseActiveRecord::EVENT_BEFORE_UPDATE//要判断的事件名称
);
以上例子表示 判断AR类数据库记录变更行为下有没有handler。
** 注:仔细阅读了源码后,发现该函数不仅会检查指定的这个类,也会检查其所有的父类。**offAll =>解除所有类级别的事件处理程序。
一个最简单的解除所有绑定:
1
2
\yii\base\Event::offAll();Yii2 内置事件
在上面我们明白了如何绑定解绑事件,Yii2也很贴心的给我们提供了许多内置的事件,在这里列举一下,以用于快速查询。Tips:此内容可以在Yii2速查表里找到。
Application # 应用主体
- 应用处理请求before之前触发
- Application::EVENT_BEFORE_REQUEST
- 应用处理请求before之后触发
- Application::EVENT_AFTER_REQUEST
Controller # 控制器
- 在每个Action运行之前触发
- Controller::EVENT_BEFORE_ACTION
- 在每个Action运行之后触发
- Controller::EVENT_AFTER_ACTION
Model # 模型
- 在验证Model属性之前触发
- Model::EVENT_BEFORE_VALIDATE
- 在验证Model属性之后触发
- Model::EVENT_AFTER_VALIDATE
Module # 模块
- 一个模块的Action运行前触发
- Module::EVENT_BEFORE_ACTION
- 一个模块的Action运行后触发
- Module::EVENT_AFTER_ACTION
View # 视图
- 执行视图的beforePage时触发
- View::EVENT_BEGIN_PAGE
- 执行视图的endPage函数时触发
- View::EVENT_END_PAGE
- 在renderFile渲染一个视图文件之前触发
- View::EVENT_BEFORE_RENDER
- 在renderFile渲染一个视图文件之后触发
- View::EVENT_AFTER_RENDER
- 执行视图的beginBody函数时触发
- View::EVENT_BEGIN_BODY
- 执行视图的endBody函数时触发
- View::EVENT_END_BODY
Widget # 挂件
- Widget初始化时触发
- Widget::EVENT_INIT
- Widget执行前触发
- Widget::EVENT_BEFORE_RUN
- Widget执行之后触发
- Widget::EVENT_AFTER_RUN
ActiveQuery
- 由ActiveQuery的init函数触发
- ActiveQuery::EVENT_INIT
BaseActiveRecord & ActiveRecord # 这也许是内置事件中最重要的一批了。
- AR对象被初始化init时触发
- BaseActiveRecord::EVENT_INIT
- AR执行查询结束时触发
- BaseActiveRecord::EVENT_AFTER_FIND
- 插入结束时触发
- BaseActiveRecord::EVENT_BEFORE_INSERT
- 插入之后触发
- BaseActiveRecord::EVENT_AFTER_INSERT
- 更新记录之前触发
- BaseActiveRecord::EVENT_BEFORE_UPDATE
- 更新记录之后触发
- BaseActiveRecord::EVENT_AFTER_UPDATE
- 删除记录之前触发
- BaseActiveRecord::EVENT_BEFORE_DELETE
- 删除记录之后触发
- BaseActiveRecord::EVENT_AFTER_DELETE
- 在数据refresh成功之后触发
- BaseActiveRecord::EVENT_AFTER_REFRESH
Connection # 数据库连接
- 数据库连接被打开后触发
- Connection::EVENT_AFTER_OPEN
- 事务被启动时触发
- Connection::EVENT_BEGIN_TRANSACTION
- 事务被提交后触发
- Connection::EVENT_COMMIT_TRANSACTION
- 事务回滚后触发
- Connection::EVENT_ROLLBACK_TRANSACTION
Response # Http响应
- Response响应发送之前触发
- Response::EVENT_BEFORE_SEND
- Response响应发送之后触发
- Response::EVENT_AFTER_SEND
- Response响应内容准备好之后触发
- Response::EVENT_AFTER_PREPARE
User # 会员登陆授权
- 登陆之前触发
- User::EVENT_BEFORE_LOGIN
- 登陆之后触发
- User::EVENT_AFTER_LOGIN
- 注销之前触发
- User::EVENT_BEFORE_LOGOUT
- 注销之后触发
- User::EVENT_AFTER_LOGOUT
一些使用技巧
使用事件不仅可以写到controller里面,实现这些用户注册成功触发SayHelloToUser事件这个场景。
也可以写到BootStrap文件中,实现一些比如全局安全检测,日志等功能。另外也可以写到配置文件中。下面简单介绍一下配置文件实现绑定事件handler的流程。
下面贴一个用户登录事件绑定的实现,代码实现了登录后修改最后登录时间。
config/main.php
1 | 'components' => [ |
上面就是在配置文件中绑定事件handler的基本形式。
大体模型如下:
1 | 'components' => [ |
一些其它需要留意的地方
- 事件是在Component引入的,yii\base\Object是不支持事件的。使用时要从yii\base\Component进行继承
- Handler的形式必须是函数形式的。
文中部分内容引用自:
[1]深入理解Yii2.0-事件
文章评论