首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii 框架中 Behavior 的定義與綁定完整指南

     編輯:PHP 綜合知識

定義 Behavior 類別

建立 Behavior 僅需繼承 yii\base\Behavior 或其子類別。範例:

namespace app\components;
use yii\base\Behavior;

class MyBehavior extends Behavior {
    public $prop1;
    private $_prop2;

    public function getProp2() { return $this->_prop2; }
    public function setProp2($value) { $this->_prop2 = $value; }

    public function foo() { /* ... */ }
}

上例定義了兩個屬性(prop1 為公有屬性,prop2 透過 getter/setter 定義)與一個方法 foo()。得益於 yii\base\Object 為祖先類別,支援以存取器定義屬性。Behavior 內部可透過 $this->owner 存取所依附的 Component。

靜態綁定:覆寫 behaviors() 方法

在 Component 子類別中覆寫 behaviors() 回傳配置陣列即可實現靜態綁定:

namespace app\models;
use yii\db\ActiveRecord;
use app\Components\MyBehavior;

class User extends ActiveRecord {
    public function behaviors() {
        return [
            // 匿名行為,僅給類名
            MyBehavior::className(),
            // 命名行為
            'myBehavior2' => MyBehavior::className(),
            // 匿名行為,含配置
            [
                'class' => MyBehavior::className(),
                'prop1' => 'value1',
                'prop3' => 'value3',
            ],
            // 命名行為,含配置
            'myBehavior4' => [
                'class' => MyBehavior::className(),
                'prop1' => 'value1',
                'prop3' => 'value3',
            ],
        ];
    }
}

亦可於應用配置檔中以 as 關鍵字綁定:

[
    'as myBehavior2' => MyBehavior::className(),
    'as myBehavior3' => [
        'class' => MyBehavior::className(),
        'prop1' => 'value1',
        'prop3' => 'value3',
    ],
]

動態綁定:attachBehaviors()

執行期呼叫 attachBehaviors():

$Component->attachBehaviors([
    'myBehavior1' => new MyBehavior,  // 命名行為
    MyBehavior::className(),          // 匿名行為
]);

陣列鍵值為行為名稱(命名行為),無鍵值者為匿名行為。命名行為可透過 getBehavior('name') 取得實例;所有行為可用 getBehaviors() 取得。

綁定內部流程深度解析

綁定涉及四個核心方法:

  • yii\base\Component::behaviors()
  • yii\base\Component::ensureBehaviors()
  • yii\base\Component::attachBehaviorInternal()
  • yii\base\Behavior::attach()

ensureBehaviors():確保行為已綁定

public function ensureBehaviors() {
    if ($this->_behaviors === null) {
        $this->_behaviors = [];
        foreach ($this->behaviors() as $name => $behavior) {
            $this->attachBehaviorInternal($name, $behavior);
        }
    }
}

此方法會在 __get()、__set()、__call()、hasEventHandlers()、on()、off() 等涉及屬性、方法、事件的操作前被呼叫,確保靜態宣告的行為已完成掛載。

attachBehaviorInternal():核心綁定邏輯

private function attachBehaviorInternal($name, $behavior) {
    if (!($behavior instanceof Behavior)) {
        $behavior = Yii::createObject($behavior); // 支援類名、配置陣列
    }
    if (is_int($name)) { // 匿名行為
        $behavior->attach($this);
        $this->_behaviors[] = $behavior;
    } else { // 命名行為
        if (isset($this->_behaviors[$name])) {
            $this->_behaviors[$name]->detach(); // 同名則替換
        }
        $behavior->attach($this);
        $this->_behaviors[$name] = $behavior;
    }
    return $behavior;
}

Behavior::attach():完成掛載

public function attach($owner) {
    $this->owner = $owner;
    foreach ($this->events() as $event => $handler) {
        $owner->on($event, is_string($handler) ? [$this, $handler] : $handler);
    }
}

做兩件事:設定 $owner 供 Behavior 存取宿主;遍歷 events() 將事件處理器掛載到 Component。

綁定機制總結

  • 綁定由 Component 發起,支援靜態(behaviors())、動態(attachBehaviors())、配置檔(as)三種方式。
  • 行為分命名與匿名,命名行為可針對性取得與移除。
  • 後綁定的同名行為會取代先前綁定者。
  • 綁定本質:設定 Behavior 的 $owner、將 Behavior 宣告的事件處理器掛載至 Component。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved