Yii 事件和行爲

一:事件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(),          // 匿名行爲
]);
相關文章
相關標籤/搜索