Yii2事件示例解析

事件能夠將自定義代碼「注入」到現有代碼中的特定執行點。 附加自定義代碼到某個事件,當這個事件被觸發時,這些代碼就會自動執行。php

在處理複雜任務時,事件能很好地起到解耦的做用。事件相對於硬編碼的方式來講也增長了服務器資源開銷,因此比較建議在任務較爲複雜時使用事件!web

如下是實例代碼,代碼中有詳細註釋:數據庫

控制器

<?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目錄下app

<?php
namespace app\models;

use yii\base\Event;

/**
 * 信息發送前的事件,這裏只充當保存數據的角色
 * Class MsgBeforeEvent
 * @package app\models
 */
class MsgBeforeEvent extends Event{
    public $date;
}

消息發送後的事件類

能夠放到models目錄下yii

<?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
相關文章
相關標籤/搜索