概念理解:在某一個事件(trigger)發生的時候,觸發預先設定(on)的代碼,這是代碼解耦的一種方式。
綁定事件、觸發事件的類繼承的是Component
,只在當前示例中運行,不與類的其餘實例發生關係,也不與其餘類、其餘實例發生關係。php
代碼示例: <?php namespace common\components; use yii\base\Component; class EventTest extends Component { const EVENT_SAY_HELLO = 'say_hello'; public function sayHello($event) { echo $event->data; $event->handled = true; } public function sayWorld($event) { echo $event->data; } } 1.綁定事件: $event = new EventTest(); $event->on(EventTest::EVENT_SAY_HELLO, [$event, 'sayHello'], 'Hello!'); $event->on(EventTest::EVENT_SAY_HELLO, [$event, 'sayWorld'], 'World!'); 2.解除事件: $event->off(EventTest::EVENT_SAY_HELLO, [$event, 'sayHello']); 3.觸發事件: $event->trigger( EventTest::EVENT_SAY_HELLO);
綁定事件、觸發事件的類繼承的是Event
,類級別事件會被類自身、類的實例、後代類、後代類實例的同一事件所觸發,影響範圍更大html
代碼示例: <?php namespace common\components; use yii\base\Event; class EventTest extends Event { const EVENT_SAY_HELLO = 'say_hello'; public function sayHello($event) { echo $event->data; } public function sayWorld($event) { echo $event->data; } } 1.綁定事件: $event = new EventTest(); $event->on('\common\components\EventTest', EventTest::EVENT_SAY_HELLO, [$event, 'sayHello'], 'Hello!'); $event->on('\common\components\EventTest', EventTest::EVENT_SAY_HELLO, [$event, 'sayWorld'], 'World!'); 2.解除事件: $event->off('\common\components\EventTest', EventTest::EVENT_SAY_HELLO, [$event, 'sayWorld']); 3.觸發事件: $event->trigger('\common\components\EventTest', EventTest::EVENT_SAY_HELLO); 類級別參數比實例級別多一個參數:類名
注意: 解除事件若是不傳 handle,則會解除該事件下的全部 handle。 在其中一個 handle 裏面加上 $event->handled = true 也會阻止後續 handle 的觸發,如上代碼。
利用Application
實例在整個應用的生命週期中全局可訪問的特性,來實現這個全局事件的。在任意須要的時候,均可以觸發全局事件,也能夠在任意必要的時候綁定,或解除一個事件。數組
代碼示例: 1.綁定事件: $event = new EventTest(); Yii::$app->on('global_event', [$event, 'globalEvent'], 'global event'); 2.觸發事件: Yii::$app->trigger('global_event'); 全局級別實際上也是一個特殊的實例。[注意所謂全局其實做用範圍也只是在當前請求的生命週期有效,而非當前會話(簡單的說,打開瀏覽器,訪問服務器,直到瀏覽器關閉,稱爲一次會話)]
實例級別經過維護Component
類的屬性 $_events
數組,觸發事件時經過[事件名稱]取到[當前實例]的handle
數據,再經過函數call_user_func
觸發handle
。瀏覽器
類級別經過維護Event
類的屬性 $_events
數組,觸發事件時經過[類名和事件名稱]取到[當前類以及父類]的handle
數據,再經過函數call_user_func
觸發handle
。服務器
Component 的 $_event
數據結構示例以下數據結構
Array ( [say_hello] => Array ( [0] => Array ( [0] => Array ( [0] => common\components\EventTest Object ( [_events:yii\base\Component:private] => Array *RECURSION* [_eventWildcards:yii\base\Component:private] => Array ( ) [_behaviors:yii\base\Component:private] => Array ( ) ) [1] => say_hello ) [1] => Hello! ) ) )
以上總結參考了深刻理解Yii2.0,其實之前就看過,可是也只是侷限於看過,沒有本身跑demo調試、查看源代碼,而後就誤覺得本身明白了,其實過倆天什麼都不記得了。因此如今經過寫博客來加深本身的理解,這篇博客其實主要講的仍是事件的使用,具體原理一帶而過,若是有小夥伴只知其一;不知其二,可能查看一下源代碼[yii\base\Component yii\base\Event
]你就明白了。因爲水平有限,歡迎小夥伴交流和指正。app