Yii2框架源碼研究1-Object

繼承樹分析

看yii2框架的源代碼會發(fā)現(xiàn),請求的入口,也就是index.php文件,相當(dāng)?shù)暮唵危谌肟谖募杏幸恍邢铝写a:

(new yii\web\Application($config))->run();

這里面實例化了一個Application類的對象,并調(diào)用了這個對象的run方法,這篇文章要記錄的,就是這個類的來龍去脈。
想要理清這個類具體是干什么的,首先來分析一下這個類的所有父類,這個類的繼承樹如下,

  • yii\web\Application
  • yii\base\Application
  • yii\base\Module
  • yii\di\ServiceLocator
  • yii\base\Component
  • yii\base\Object
  • yii\base\Configurable

這個列表后邊的依次是前面的父類。那么現(xiàn)在就從下往上依次研究一下這些類。

yii\base\Configurable

這個類只是一個很簡單的接口,原代碼如下:

interface Configurable
{
}

竟然什么都沒有。。。那么這個類的功能到底是什么呢,通過查看注釋可以看出,這個Configurable接口其實就是定義了一種約定,所有實現(xiàn)這個接口的類都必須滿足一個條件,這個條件就是這個類的構(gòu)造函數(shù)的最后一個參數(shù)是一個配置數(shù)組,其中key為這個類對應(yīng)的屬性,value為屬性對應(yīng)的值。構(gòu)造函數(shù)需要采用如下的形式:

  public function __constructor($param1, $param2, ..., $config = []) ```
  這個類很簡單,接下來繼續(xù)來看。
## yii\base\Object
  先來看一下這個類的方法有哪些:
```php
class Object implements Configurable
{

    public static function className()
    {
        return get_called_class();
    }
    public function __construct($config = [])
    {
        if (!empty($config)) {
            Yii::configure($this, $config);
        }
        $this->init();
    }
    public function init(){
        
    }
    public function __get($name)
    public function __set($name, $value)
    public function __isset($name)
    public function __unset($name)
    public function __call($name, $params)
    public function hasProperty($name, $checkVars = true)   
    public function canGetProperty($name, $checkVars = true)    
    public function canSetProperty($name, $checkVars = true)    
    public function hasMethod($name)
}

其中只有init是個空方法。需要說明一點的是,yii\base\Object這個類提供了yii2框架所采用的一個非常重要的特性:屬性。屬性用來表示對象的狀態(tài),定義一個屬性通常采用如下的方法:

private $_label;//第一步,定義一個private的屬性
public function getLabel() // 設(shè)置get方法,可讀屬性
{
    return $this->_label;
}
public function setLabel($value) //設(shè)置set方法,可寫屬性
{
    $this->_label = $value;
}

上面是對屬性這個概念進行分析,Object對象是怎么提供這個特性的呢,這里首先要看一下構(gòu)造函數(shù)中的代碼:

Yii::configure($this, $config);

定位到這個函數(shù):

public static function configure($object, $properties)
    {
        foreach ($properties as $name => $value) {
            $object->$name = $value;
        }
        return $object;
    }

看起來好簡單的樣子,遍歷,然后屬性賦值。當(dāng)調(diào)用類不存在的屬性時會調(diào)用魔術(shù)方法,Object類重載了魔術(shù)方法:

    public function __set($name, $value)
    {
        $setter = 'set' . $name;
        if (method_exists($this, $setter)) {
            $this->$setter($value);
        } elseif (method_exists($this, 'get' . $name)) {
            throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
        } else {
            throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
        }
    }

當(dāng)賦值某一個不存在的屬性時會去調(diào)用相應(yīng)的set方法,相應(yīng)的獲取某個屬性的值會調(diào)用get方法。
  每個Object子類如果有構(gòu)造方法,在其中一定會調(diào)用父類的構(gòu)造方法,并將property數(shù)組傳遞過去,由此終于知道Object類怎么實現(xiàn)屬性這個特性了。如果我們想要以及編寫的類擁有屬性這個特性,首先需要為每一個屬性設(shè)定相應(yīng)的get和set方法,然后在實例化的時候傳遞一個配置數(shù)組,將這個數(shù)組傳遞到父類的構(gòu)造函數(shù)就行了。所以在入口文件,實例化Application的時候,傳遞了一個$config數(shù)組,里面的key便是這個Application的一個個屬性。
  還需要注意的一點就是,在Object的構(gòu)造函數(shù)中,調(diào)用了init方法進行一些初始化,在子類中可以覆蓋這個方法進行一些初始化的操作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,638評論 18 399
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,488評論 2 7
  • date: 2017-11-21 18:15:18title: yii 源碼解讀 百度腦圖 - yii 源碼解析:...
    daydaygo閱讀 3,600評論 1 11
  • 在分析一件事情值不值得去做、花多少精力去做的時候,可以從兩個角度來評估:一是這件事在當(dāng)下將給“我”帶來的收益大小,...
    Fly_Catkin閱讀 272評論 0 0

友情鏈接更多精彩內(nèi)容