Yii 2.0 中事件的使用

关于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

时间: 2024-08-01 22:39:55

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

Yii2.0中Yii::$app与Yii 1.0中Yii:app()的理解

一直不明白Yii::$app与Yii::app(),查找yii框架源码后如下记录分享 (1)在Yii1.0中Yii::app()返回的是你在index.php里创建的CWebApplication实例,在对应的CWebApplication,入口文件: Yii::createWebApplication($configFile)->run(); 对应的类中查找: public static function createWebApplication($config=null){return se

yii 2.0 属性

属性(Property) 属性用于表征类的状态,从访问的形式上看,属性与成员变量没有区别. 你能一眼看出 $object->foo 中的foo 是成员变量还是属性么?显然不行. 但是,成员变量是就类的结构构成而言的概念,而属性是就类的功能逻辑而言的概念,两者紧密联系又 相互区别.比如,我们说People类有一个成员变量 int $age ,表示年龄.那么这里年龄就是属性 , $age 就是成员变量. 再举个更学术化点的例子,与非门: 1 2 3 4 5 6 7 8 9 10 11 12 13 1

.NET Framework 2.0中的数据访问新特性

1. 异步数据访问 ? 支持异步数据编程 ? SqlConnection – BeginOpen – EndOpen ? SqlCommand – BeginExecuteNonQuery – BeginExecuteReader – BeginExecuteXmlReader – EndExecuteNonQuery – EndExecuteReader – EndExecuteXmlReader 2. 多活动结果集(MARS) ? 在 SQL Server 2005 中支持多活动结果集 ?

Qt中事件分发源代码剖析(一共8个步骤,顺序非常清楚:全局的事件过滤器,再传递给目标对象的事件过滤器,最终传递给目标对象)

Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的.下面举例说明: 1)首先看看下面一段示例代码: [cpp] view plaincopy int main(int argc, char *argv[]) { QApplication a(argc, argv); MouseEvent w; w.show(); return a.exec(); } 2)a.exec进入事件循环,调用的是QAppli

Cocos2d-x 3.0 中使用单点触摸

Cocos2d-x 3.0 中使用单点触摸 尊重原创:http://cn.cocos2d-x.org/tutorial/show?id=2712 在游戏中,经常会用到触摸,大部分游戏也是通过触摸控制游戏角色运动的,在Cocos2d-x 3.0中使用了新的触摸机制,Cocos2d-x 3.0中摒弃了Cocos2d-x 2.0中将要触发的事件交给代理(delegate)处理,再通过实现代理里面的onTouchBegan等方法接收事件,最后完成事件的响应,在Cocos2d-x 3.0中只需通过创建一个

在 Flash ActionScript 2.0 中调用 Javascript 方法

本篇文章由:http://xinpure.com/call-the-javascript-method-in-flash-actionscript-2-0/ 在 Flash ActionScript 2.0 中调用 Javascript 方法 最近在工作中,有个这样的需求: 要从 Flash ActionScript 2.0 中调用网页上的 Javascript 方法 这是一个关于 Flash 和 Javascript 交互的问题. 在 ActionScript 2.0 中调用外部 javasc

Yii Framework2.0开发教程(8)输入验证

validate() 方法,在幕后为执行验证操作.先看一个简单的例子,例子的代码在<Yii Framework2.0开发教程(2)使用表单Form>. 类ZhyoulunController中函数actionEntry() ,其中有一句$model->validate(),就是来判断输入的名字和电子邮件是否正确. 修改models/EntryForm.php <?php namespace app\models; use yii\base\Model; class EntryFor

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

1.修改窗口背景色或者光标形状 在OpenCV1.0版本利用函数int cvNamedWindow( const char* name, int flags )初始化创建一个窗口后,窗口的背景色是灰色,光标形状是十字线,通过如下方法改变这些窗口属性: 第一种方法是从源头直接修改.(1) 打开OpenCV安装目录下的_make文件夹,使用VC6.0打开opencv.dsw工程,打开文件”…\\highgui\\window_win32.cpp” 找到函数CV_IMPL int cvInitSyst

Cocos2d-x 3.0中实现多点触摸

Cocos2d-x 3.0中实现多点触摸 尊重原创:http://cn.cocos2d-x.org/tutorial/show?id=2713 在上一篇<Cocos2d-x 3.0 中使用单点触摸>中介绍了在Cocos2d-x 3.0中实现单点触摸,但是有些游戏还会用到多点触摸,其中最典型的游戏是节奏大师,在节奏大师中会不断产生运动的音符,玩家需要不停地点击音符以获得高分,而且玩家可以多个手指头一起点,多个手指头一起点就是使用多点触摸实现的. 下面通过一个小的例子介绍如何在Cocos2d-x