淺析Yii2.0的屬性Property

概念理解:第一次看 深刻理解Yii2.0的時候,我也是懵逼的,屬性不就是類的屬性嗎,有什麼好說的。後來才知道Yii框架對成員變量和屬性作了區分,那類的成員變量和屬性究竟是什麼關係又有什麼區別呢?先看一下比較書面化的說法,"成員變量是就類的結構構成而言的概念,而屬性是就類的功能邏輯而言的概念,二者緊密聯繫又相互區別"。說白點就是屬性是業務上抽象出來的概念,而且屬性的代碼實現依賴於成員變量,但不能說屬性就是成員變量,(好像也不是很直白...)而且屬性在代碼上能夠作到控制讀寫權限,而成員變量就不能夠了。

屬性的實現步驟

  • 繼承自 yii\base\BaseObject
  • 聲明一個用於保存該屬性的私有成員變量。
  • 提供gettersetter函數,或二者都提供,用於訪問、修改上面提到的私有成員變量。 若是隻提供了getter,那麼該屬性爲只讀屬性,只提供了setter,則爲只寫。

屬性的實現demo

<?php

namespace common\components;

use yii\base\BaseObject;


class Article extends BaseObject
{
    //成員變量
    private $_val = '我是初始值';

    //控制屬性讀權限的方法
    public function getTitle()
    {
        return $this->_val;
    }

    //控制屬性寫權限的方法
    public function setTitle($value)
    {
        $this->_val = $value;
    }
}

$obj = new Article();

//獲取屬性文章標題的值
$obj->title;                            

//設置屬性文章標題的值
$obj->title = 'mysql從入門到刪庫';
注意:

上述demo中,$_val 就是成員變量 title 就是一個抽象出來的業務屬性。

從Yii2.0.13之後推薦繼承的是 yii\base\BaseObject,而不是 yii\base\Object 由於在 php7.2 之後 Object 是保留字,不能再做爲類名

那麼Yii是怎麼經過getTitle()setTitle()函數來控制屬性title的讀寫的呢?其實很簡單,經過__get()__set()倆個魔術方法來實現的。php

屬性的實現原理

下面是類BaseObject裏面對於__set()__get()魔術方法的實現。html

public function __get($name)
    {
        $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
            return $this->$getter();
        } elseif (method_exists($this, 'set' . $name)) {
            throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
        }

        throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
    }

    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);
        }
    }

當咱們讀取類Article實例裏面title值的時候,會去遍歷類Article裏面的屬性,找不到匹配的屬性的時候,就會自動觸發__get()魔術方法[注:當調用當前環境下未定義或不可見的類屬性時自動觸發],在__get()方法裏再去調用getTitle()方法。設置屬性title同理。[注:因爲PHP對於類方法不區分大小寫,即大小寫不敏感, $obj->getTitle() 和 $obj->gettitle() 是調用相同的函數]mysql

小結

以上總結參考了深刻理解Yii2.0[此次可能參考的比較多,嘿嘿],其實之前就看過,可是也只是侷限於看過,沒有本身跑demo調試、查看源代碼,而後就誤覺得本身明白了,其實過倆天什麼都不記得了。因此如今經過寫博客來加深本身的理解,因爲水平有限,歡迎小夥伴交流和指正。sql

相關文章
相關標籤/搜索