通過事件(Event)處理,可以在某個特定時刻執行指定的代碼,可以解耦代碼,同時也增加了可維護性,通常,事件在客戶端軟件中比較好理解,比如onClick,onFocus,當點擊按鈕,獲取到焦點時執行指定代碼。在PHP中,事件的處理可能不太好理解,但是,只要理清了事件處理的過程,一切都會變得簡單:
1.注冊(或者說綁定)針對某個動作事件的處理器(handler)
2.觸發某個動作事件
3.觸發1中注冊(綁定)的處理器
4.執行處理器中的代碼
下面以 貓叫鼠跑 這個例子來簡單說明Yii2中的事件處理。
Controller中的代碼:
public function actionTest(){ $cat = new Cat('Tom'); $mouse = new Mouse('Jerry'); $data = array('msg'=>'miaow miaow miaow!'); //注冊Cat::EVENT_AFTER_SHOUT事件響應(這里對Cat的EVENT_AFTER_SHOUT響應$mouse 的runout方法) $cat->on(Cat::EVENT_AFTER_SHOUT, [$mouse,'runout'], $data); //觸發shout事件 $cat->shout(); }
Cat類代碼:
public function actionTest(){ $cat = new Cat('Tom'); $mouse = new Mouse('Jerry'); $data = array('msg'=>'miaow miaow miaow!'); //注冊Cat::EVENT_AFTER_SHOUT事件響應(這里對Cat的EVENT_AFTER_SHOUT響應$mouse 的runout方法) $cat->on(Cat::EVENT_AFTER_SHOUT, [$mouse,'runout'], $data); //觸發shout事件 $cat->shout(); }
Mouse類代碼:
class Mouse extends \yii\base\Component{ private $_name; function __construct($_name) { $this->_name = $_name; } public function runout($event){ //事件名稱,事件數據,事件發送者 var_dump($event->name,$event->data,$event->sender); echo 'Cat is shouting,I am a mouse so I need to run!'; } }
執行actionTest時,會依次輸出以下結果
I am a Cat,I am shouting!
Cat is shouting,I am a mouse so I need to run!
在Yii2中,事件分為三個級別:
1.實例事件(同上面的例子,僅對某個實例有效)
2.類事件(對整個類有效)
yii\base\Event::on( Cat::className(), // 第一個參數表示事件發生的類 Cat::EVENT_AFTER_SHOUT, // 第二個參數表示是什么事件 function ($event) { // 對事件的處理 echo $event->sender; } );
3.全局事件(對全局有效)
Yii::$app->on('eventName', function ($event) { echo get_class($event->sender); // 顯示當前觸發事件的對象的類名稱 });
除了綁定事件外,某些場合也需要移除綁定的事件,常用方法有以下幾種:
// 刪除所有EVENT_AFTER_SHOUT事件的handler $cat->off(Cat::EVENT_AFTER_SHOUT); // 刪除一個對象的成員函數的handler $cat->off(Cat::EVENT_AFTER_SHOUT, [$mouse, 'runout']); // 刪除一個PHP全局函數的handler $cat->off(Cat::EVENT_AFTER_SHOUT, 'global_onAfterShout');