一:事件php
事件能夠將自定義代碼「注入」到現有代碼中的特定執行點。 附加自定義代碼到某個事件,當這個事件被觸發時,這些代碼就會自動執行,例如當咱們向數據庫的一個表中新增數據時,若是你想要在新增數據以前或新增數據以後執行指定的操做的話,這時候咱們就能夠使用事件來實現數據庫
如:數組
在表對應的模型的init方法中添加:frontend
//新增數據以前事件,處理器是對象方法 $this->on(Country::EVENT_BEFORE_INSERT, [$this, 'function_name']); //新增數據以後,處理器是匿名函數 $this->on(Country::EVENT_AFTER_INSERT,function ($event) { echo '新增數據以後'; });
處理器是對象方法的在模型中新增一個function_name方法,該方法爲當指定事件觸發時執行yii
public function function_name($event) { echo '新增數據以前'; }
事件處理器調用yiibaseComponent::on() 方法來附加處理器到事件上,該方法的第三個參數的數據,在在事件被觸發和處理器被調用時能被處理器使用函數
能夠使用以下方法獲取this
$event->data
在模型中在事件觸發後咱們能夠使用以下獲取對應的表數據spa
$event->sender
若是你想要在執行指定的事件處理器以後,中止後續的事件處理器調用,能夠設置 $event 參數的 yii\base\Event::$handled 屬性爲真,這時候這個事件處理器以後的處理器都不會再執行了code
$event->handled = true;
若是你想要將指定的事件觸發器在事件觸發以後第一個執行的話,能夠在調用yiibaseComponent::on()方法時將第四個參數設置爲false對象
$this->on(Country::EVENT_AFTER_INSERT,function ($event) { echo '新增數據以後'; }, null, false);
上面咱們使用的觸發事件都是Yii建立寫好的現成事件,若是咱們想要本身寫一個事件的話,以下:
這裏我建立一個EVENT_HELLO事件
const EVENT_HELLO = 'hello'; //當執行sayHello時觸發hello事件 public function sayHello() { $this->trigger(self::EVENT_HELLO); }
如上咱們建立了一個觸發事件,當咱們調用sayHello方法後,這時候咱們會觸發一個名爲hello的事件
調用:
$this->sayHello();
事件處理器:
$this->on(self::EVENT_HELLO, function ($event) { echo 111; });
如上,當咱們調用sayHello方法後,這時候頁面上會輸出111
二:行爲
1:建立行爲類:
行爲是 yiibaseBehavior或其子類的實例,能夠無須改變類繼承關係便可加強一個已有的組件類功能,當行爲附加到組件後,它將「注入」它的方法和屬性到組件,,而後能夠像訪問組件內定義的方法和屬性同樣訪問它們
以下定義了一個行爲
<?php namespace frontend\behavior; use yii\base\Behavior; class TestBehavior extends Behavior { /** * 內部屬性message */ private $_message; /** * 獲取message屬性 */ public function getMessage() { return $this->_message; } /** * 設置message屬性 */ public function setMessage($value) { $this->_message = $value; } }
如上就是一個最簡單的行爲類,咱們還能夠讓行爲類來相應對應組件的事件觸發,這時候咱們能夠複寫yiibaseBehavior::events() 方法
以下建立了一個用戶在新增和更新數據以前執行的行爲類
<?php namespace frontend\behavior; use yii\base\Behavior; use yii\db\ActiveRecord; class TestBehavior extends Behavior { public function events() { return [ ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeUpdate', ActiveRecord::EVENT_BEFORE_INSERT => 'beforeInsert', ]; } public function beforeUpdate($event) { //業務代碼 } public function beforeInsert($event) { //業務代碼 } }
2:附件行爲類(使用行爲類)
咱們能夠靜態或動態地附加行爲到組件
(1):靜態附加行爲類
要靜態附加行爲,覆寫行爲要附加的組件類的behaviors()方法便可。 behaviors()方法應該返回行爲配置列表。 每一個行爲配置能夠是行爲類名也能夠是配置數組
如:
public function behaviors() { return [ // 匿名行爲,只有行爲類名 TestBehavior::className(), // 命名行爲,只有行爲類名 'testBehavior' => TestBehavior::className(), // 匿名行爲,配置數組 [ 'class' => TestBehavior::className(), 'message' => 'value1', ], // 命名行爲,配置數組 'myBehavior4' => [ 'class' => TestBehavior::className(), 'message' => 'value1', ] ]; }
(2):動態附加行爲類
要動態附加行爲,在對應組件裏調用 yiibaseComponent::attachBehavior() 方法便可
// 附加行爲對象 $this->attachBehavior('testBehavior', new TestBehavior()); // 附加行爲類 $this->attachBehavior('testBehavior', TestBehavior::className()); // 附加配置數組 $this->attachBehavior('testBehavior', [ 'class' => TestBehavior::className(), 'message' => 'value1', ]); //一次附加多個行爲類 $this->attachBehaviors([ 'testBehavior' => new TestBehavior, // 命名行爲 TestBehavior::className(), // 匿名行爲 ]);