关于PHP的事件处理,参照

http://www.cnblogs.com/mafeifan/p/4322238.html

http://www.cnblogs.com/mafeifan/p/4322271.html

为什么要使用事件?可能我们会有下面的业务需求,每当一个新用户注册成功会我们要给管理员发封邮件,还要有推送通知。

之前的代码可能是这样

if($model->save()){
// 注册成功, 跳转
}

要变成这样

if($model->save()){
$mailObj->sendNewUserMail($model);
$notification->setNotification($model);
}

目前看起来也没这么不好的,但是随着业务的发展,如果当用户注册后要去处理10件事情,我们一直要往save()下面塞逻辑?

事件就是对应这种类似场景的。

在Yii2.0中使用事件其实非常简单。下面是一个例子。

1. 定义事件名

在common\models\User模型文件中,定义一个事件名。

对你看到了,Yii2.0中事件名用常量定义,好处是由于PHP变量区别大小写。这样写既保证唯一又不容易出错。

 const EVENT_NEW_USER = 'new-user';

2. 定义事件要去处理的事情,就是各种方法啦。

    public function sendMail($event){
echo 'mail sent to admin';
// you code
} public function notification($event){
echo 'notification created';
}

直接写在User模型好像不太好,应该有专门的发送邮件及通知的模块。这里不是重点。

3. 接着在User文件中。将执行的逻辑放到一个统一的方法中。

public function init(){
$this->on(self::EVENT_NEW_USER, [$this, 'sendMail');
$this->on(self::EVENT_NEW_USER, [$this, 'notification');
}

4. 最后在Controller中。调用事件就OK了。

if($model->save()){
$model->trigger(User::EVENT_NEW_USER);
}

Yii2.0中绑定事件用on()方法,解除用off()方法,调用事件用trigger()方法。

    /**
* 测试事件1
* 使用匿名函数
*/
public function actionTestEvent1(){
$user = new User();
// 使用匿名函数
$user->on(User::EVENT_NEW_USER,function(){
echo 'run~';
});
$user->trigger(User::EVENT_NEW_USER);
$user->off(User::EVENT_NEW_USER);
$user->trigger(User::EVENT_NEW_USER);
die();
}

这是用一个匿名函数来绑定到EVENT_NEW_USER事件中。

3. 在User模型中添加一个方法。

绑定方法到事件上,

$user->on(User::EVENT_NEW_USER,[$user,'sendMail']);

注意这句的意思是将$user对象中的sendMail方法绑定到User::EVENT_NEW_USER事件上。

    /**
* 测试事件2
* 使用类中的方法
*/
public function actionTestEvent2(){
$user = new User();
// 使用匿名函数
$user->on(User::EVENT_NEW_USER,[$user,'sendMail']);
$user->trigger(User::EVENT_NEW_USER);
$user->off(User::EVENT_NEW_USER);
die();
}

类似的,直接使用类里面的方法

    /**
* 测试事件3
* 使用类中的方法
*/
public function actionTestEvent3(){
// \common\components\EventTest::Bar();
$user = new User();
// 使用匿名函数
$user->on(User::EVENT_NEW_USER,['common\components\EventTest','Bar']);
$user->trigger(User::EVENT_NEW_USER);
die();
}

需要创建EventTest类文件

namespace common\components;
use Yii;
use yii\base\Component;
use yii\base\Event; class EventTest extends Component
{
const EVENT_HELLO = 'hello'; public function Bar(){
echo 'run method';
}
}

总结一下。

附件事件处理有四种方法:

$foo = new Foo;

// 处理器是全局函数
$foo->on(Foo::EVENT_HELLO, 'function_name'); // 处理器是对象方法
$foo->on(Foo::EVENT_HELLO, [$object, 'methodName']); // 处理器是静态类方法
$foo->on(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']); // 处理器是匿名函数
$foo->on(Foo::EVENT_HELLO, function ($event) {
//事件处理逻辑
});

关于事件的执行顺序及级别,可以查看文档:http://www.yiichina.com/doc/guide/2.0/concept-events

Yii 2.0 中事件的使用的更多相关文章

  1. as3.0中如何阻止事件冒泡

    原作者:菩提树下的杨过转载出处:http://yjmyzz.cnblogs.com 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究 ...

  2. yii 2.0 代码阅读 小记

    1.\yii\base\object 设置了get/set属性...使用getName()获取属性名..构造函数中使用config初始化属性 2.\yii\base\Component 继承自Obje ...

  3. [译] C# 5.0 中的 Async 和 Await (整理中...)

    C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...

  4. [Yii2.0] 以Yii 2.0风格加载自定义类或命名空间 [配置使用Yii2 autoloader]

    Yii 2.0最显著的特征之一就是引入了命名空间,因此对于自定义类的引入方式也同之前有所不同.这篇文章讨论一下如何利用Yii 2.0的自动加载机制,向系统中引入自定义类和命名空间.本文旨在抛砖引玉,如 ...

  5. FineUI(开源版)v6.0中FState服务器端验证的实现原理

    前言 1. FineUI(开源版)是完整开源,最早发起于 2008-04,下载全部源代码:http://fineui.codeplex.com/ 2. 你可以通过捐赠作者来支持FineUI(开源版)的 ...

  6. AppBox v6.0中实现子页面和父页面的复杂交互

    前言 1. AppBox是捐赠开源(获取源代码至少需要捐赠作者 1 元钱),基于的 FineUI(开源版)则是完整开源,网址:http://fineui.codeplex.com/ 2. 你可以通过捐 ...

  7. Hadoop2.6.0的事件分类与实现

    前言 说实在的,在阅读Hadoop YARN的源码之前,我对于java枚举的使用相形见绌.YARN中实现的事件在可读性.可维护性.可扩展性方面的工作都值得借鉴. 概念 在具体分析源码之前,我们先看看Y ...

  8. 关于JAVA中事件分发和监听机制实现的代码实例-绝对原创实用

    http://blog.csdn.net/5iasp/article/details/37054171 文章标题:关于JAVA中事件分发和监听机制实现的代码实例 文章地址: http://blog.c ...

  9. 有关OpenCV1.0中GUI命令的几个函数学习总结

    1.修改窗口背景色或者光标形状 在OpenCV1.0版本利用函数int cvNamedWindow( const char* name, int flags )初始化创建一个窗口后,窗口的背景色是灰色 ...

随机推荐

  1. C++Primer学习笔记《三》

    数组名事实上就是一个常指针,指向数组元素中第一个的地址,在程序中假设要用指针遍历数组,不能直接用数组名来自增或自减.由于它是常量,一般先把数组名保存一份同类型的指针,然后再用这个指针来自增或是自减来实 ...

  2. Django的视图响应类型

    Django的视图响应类型 一. 视图函数编写原则 视图函数接受HTTP请求并返回响应,可以放在任何地方,可以是任何功能:视图函数可以返回Web文本,页面.重定向.错误.图片等任何内容:视图函数通过H ...

  3. 10、Web Service-IDEA-jaxrs 整合spring

    1.服务端的开发 1.web项目目录 2.pom <?xml version="1.0" encoding="UTF-8"?> <projec ...

  4. gdbt与adboost(或者说boosting)区别

    boosting 是一种将弱分类器转化为强分类器的方法统称,而adaboost是其中的一种,或者说AdaBoost是Boosting算法框架中的一种实现 https://www.zhihu.com/q ...

  5. Golang 单元测试和性能测试

    开发程序其中很重要的一点是测试,我们如何保证代码的质量,如何保证每个函数是可运行,运行结果是正确的,又如何保证写出来的代码性能是好的,我们知道单元测试的重点在于发现程序设计或实现的逻辑错误,使问题及早 ...

  6. urlparse 用法

    ifrom urllib2 import urlparse ‘’ captcha_id = urlparse.parse_qs(urlparse.urlparse(link).query, True) ...

  7. utils.js文件;一些常用方法的备份

    一些常用方法备份: function _(value) { value = '0' + value; return value.substr(value.length - 2); } Date.pro ...

  8. HDU 1233 还是畅通工程(Kruskal算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1233 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)   ...

  9. VPP(Vector Packet Processing)配置工具

    前言 VPP提供了一个配置工具,让用户可以简单快捷地配置VPP.用户可以通过一些简单的命令配置VPP,功能包括安装及一些基本配置和测试用例. 使用 先安装一个python的pip模块,使用pip安装V ...

  10. HTML小记

    1.页面内跳转 当<a>元素用于页面内的锚点跳转时,应该先为该页面设置一些锚点,而定义锚点有两种办法: 通过<a>元素的name属性来定义,如:<a name=" ...