事件可以將自定義程式碼“注入”到現有程式碼中的特定執行點。 附加自定義程式碼到某個事件,當這個事件被觸發時,這些程式碼就會自動執行。
在處理複雜任務時,事件能很好地起到解耦的作用。事件相對於硬編碼的方式來說也增加了伺服器資源開銷,所以比較建議在任務較為複雜時使用事件!
以下是例項程式碼,程式碼中有詳細註釋:
控制器
<?php
namespace appcontrollers;
use appmodelsMsgAfterEvent;
use appmodelsMsgBeforeEvent;
use appmodelsMsgHandler;
use Yii;
use yiiwebController;
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 "傳送資訊...
";
//任務執行完畢後,呼叫傳送資訊後的事件
$msgAfter = new MsgAfterEvent();
$msgAfter->from = `Jack`;
$msgAfter->to = `Lucy`;
$msgAfter->message = `Awesome`;
//觸發傳送資訊後的事件
$this->trigger(self::AFTER_SEND,$msgAfter);
}
}
事件處理類
個人覺得可以直接放在models目錄下,如果不需要用到資料庫操作,可以考慮直接繼承Model
<?php
namespace appmodels;
use yiiaseModel;
/**
* 資訊傳送事件處理類
* Class MsgHandler
* @package appmodels
*/
class MsgHandler extends Model{
/**
* 處理髮送資訊前的事件
* @param MsgBeforeEvent $event
*/
public function beforeSendMsg(MsgBeforeEvent $event){
//從event中讀取日期、和附加資訊
$logContent = "BEFORE:".$event->date.`,extraMsg:`.$event->data."
";
//寫入檔案中
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."
";
file_put_contents(`log.txt`,$logContent,FILE_APPEND);
}
}
訊息傳送前的事件類
可以放到models目錄下
<?php
namespace appmodels;
use yiiaseEvent;
/**
* 資訊傳送前的事件,這裡只充當儲存資料的角色
* Class MsgBeforeEvent
* @package appmodels
*/
class MsgBeforeEvent extends Event{
public $date;
}
訊息傳送後的事件類
可以放到models目錄下
<?php
namespace appmodels;
use yiiaseEvent;
/**
* 傳送資訊後的事件
* Class MsgAfterEvent
* @package appmodels
*/
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