yii2中組件爲什麼能直接使用行爲的屬性 - 揭祕不同的get函數。

上幾篇咱們講解了如何爲一個組件類配置行爲及其運行原理,本篇爲你們講解yii2組件是如何作到像訪問本身屬性同樣訪問行爲的屬性。php

首先要說的是這並不複雜,可是它能夠解決你以前的不少疑問,好比爲什麼必須是繼承組件(Component)的類才能使用行爲。咱們都知道在php中有一個魔術方法__get,咱們須要先了解一下它。yii2

先解釋一下__get方法app

當訪問不存在或者不能訪問的成員變量時對象會自動調用__get()方法.yii

begin

就是經過這個方法,yii2的Component類訪問到了關聯行爲的屬性。函數

看看文件 vendor/yiisoft/yii2/base/Component.php line127 __get方法。學習

public function __get($name) {
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        // read property, e.g. getName()
        return $this->$getter();
    }

    // behavior property
    $this->ensureBehaviors();
    foreach ($this->_behaviors as $behavior) {
        if ($behavior->canGetProperty($name)) {
            return $behavior->$name;
        }
    }
    ...
}

函數首先判斷了 method_exists($this, $getter) 是否存在,若是存在則調用,還記得你如何定義AR的關聯方法麼,就是這段代碼實現的。this

接下來咱們看重頭戲,首先 Component 執行了自身的 $this->ensureBehaviors(); 上一篇咱們學習了這個函數保證了全部相關行爲對象都各就各位,而後函數遍歷了全部行爲對象。spa

若是 $behavior->canGetProperty($name) 爲真,則返回行爲的相關屬性(這個屬性必須是public的),實現下面的結果code

$model = new User();

$model->name;
↓
$model->__get('name');
↓ //$behavior->canGetProperty($name)
return $behavior->name;

就是這樣的邏輯。你明白了麼?component

canGetProperty

接下來講說 canGetProperty 函數,這是object的一個方法,咱們知道Component和Behavior都是它的子類,這個方法主要用於判斷一個屬性是否存在。

所以就是判斷在對應行爲對象中屬性是否存在,就像上面的 $behavior 的 name屬性,若是能訪問到天然是好,不然這又是一次輪迴,調用__get方法看看getName函數是否存在,若是存在也是能夠的,好比下面的行爲注入到User類

<?php
namespace app\components;

use yii\base\Behavior;

class HelloBehavior extends Behavior {

    public function getName(){
        return "abei20172";
    }
}


// action
$model = new User();
echo $model->name;//abei20172

要注意 canGetProperty 只是判斷屬性是否存在,並不會檢查其範圍是否爲 public, private, protected。固然最後只有public才能正確訪問。

以下代碼

namespace app\components;

use yii\base\Behavior;

class HelloBehavior extends Behavior {
    protected $name = "abei2017";
}


// action
$model = new User();
echo $model->name;

咱們會獲得一個異常。

taLsjEudc7uJMLyI82oCYuy3gwlji3ek-1503373204.png

就這樣

咱們經過__get方法實現了行爲屬性對組件類的注入,如今你明白爲啥能直接訪問了吧?下一篇咱們說說行爲方法的注入原理。

qmd.png

相關文章
相關標籤/搜索