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