事件可以将自定义代码“注入”到现有代码中的特定执行点。 附加自定义代码到某个事件,当这个事件被触发时,这些代码就会自动执行。
在处理复杂任务时,事件能很好地起到解耦的作用。事件相对于硬编码的方式来说也增加了服务器资源开销,所以比较建议在任务较为复杂时使用事件!
以下是实例代码,代码中有详细注释:
控制器
<?php
namespace app\controllers;
use app\models\MsgAfterEvent;
use app\models\MsgBeforeEvent;
use app\models\MsgHandler;
use Yii;
use yii\web\Controller;
class EventTestController extends Controller{
const BEFORE_SEND = 'before_send_msg';
const AFTER_SEND = 'after_send_msg';
public function init()
{
parent::init(); // TODO: Change the autogenerated stub
$this->registerEventHandler();
}
/**
* 事件注册
*/
private function registerEventHandler(){
//事件处理类
$msgHandler = new MsgHandler();
//绑定事件时,可以传入第三个参数。该参数值将会保存到Event类的data属性中
$this->on(self::BEFORE_SEND,[$msgHandler,'beforeSendMsg'],'who');
$this->on(self::AFTER_SEND,[$msgHandler,'afterSendMsg']);
}
/**
* 测试用的方法
*/
public function actionIndex(){
//发送信息前的事件类
$msgBefore = new MsgBeforeEvent();
$msgBefore->date = date('Y-m-d H:i:s',time());
//触发发送信息前的事件,传入事件类的实例对象,这里的对象充当了保存临时数据的角色
$this->trigger(self::BEFORE_SEND,$msgBefore);
//假设这里是个较为复杂的任务
echo "发送信息...\n";
//任务执行完毕后,调用发送信息后的事件
$msgAfter = new MsgAfterEvent();
$msgAfter->from = 'Jack';
$msgAfter->to = 'Lucy';
$msgAfter->message = 'Awesome';
//触发发送信息后的事件
$this->trigger(self::AFTER_SEND,$msgAfter);
}
}
事件处理类
个人觉得可以直接放在models目录下,如果不需要用到数据库操作,可以考虑直接继承Model
<?php
namespace app\models;
use yii\base\Model;
/**
* 信息发送事件处理类
* Class MsgHandler
* @package app\models
*/
class MsgHandler extends Model{
/**
* 处理发送信息前的事件
* @param MsgBeforeEvent $event
*/
public function beforeSendMsg(MsgBeforeEvent $event){
//从event中读取日期、和附加信息
$logContent = "BEFORE:".$event->date.',extraMsg:'.$event->data."\n";
//写入文件中
file_put_contents('log.txt',$logContent,FILE_APPEND);
}
/**
* 处理发送信息后的事件
* @param MsgAfterEvent $event
*/
public function afterSendMsg(MsgAfterEvent $event){
/**
* 从event中读取数据
*/
$logContent = "AFTER!".$event->from.'发送给'.$event->to.',内容如下:'.$event->message."\n";
file_put_contents('log.txt',$logContent,FILE_APPEND);
}
}
消息发送前的事件类
可以放到models目录下
<?php
namespace app\models;
use yii\base\Event;
/**
* 信息发送前的事件,这里只充当保存数据的角色
* Class MsgBeforeEvent
* @package app\models
*/
class MsgBeforeEvent extends Event{
public $date;
}
消息发送后的事件类
可以放到models目录下
<?php
namespace app\models;
use yii\base\Event;
/**
* 发送信息后的事件
* Class MsgAfterEvent
* @package app\models
*/
class MsgAfterEvent extends Event{
public $from;
public $to;
public $message;
}
处理结果
运行控制器中的index方法后,在log.txt文件中得到如下结果
BEFORE:2017-11-08 14:10:07,extraMsg:who
AFTER!Jack发送给Lucy,内容如下:Awesome
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。