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

posted @ 2015-03-08 21:45  飞凡123  阅读(1328)  评论(0编辑  收藏  举报