概念理解:第一次看 深刻理解Yii2.0的時候,我也是懵逼的,屬性不就是類的屬性嗎,有什麼好說的。後來才知道Yii框架對成員變量和屬性作了區分,那類的成員變量和屬性究竟是什麼關係又有什麼區別呢?先看一下比較書面化的說法,"成員變量是就類的結構構成而言的概念,而屬性是就類的功能邏輯而言的概念,二者緊密聯繫又相互區別"。說白點就是屬性是業務上抽象出來的概念,而且屬性的代碼實現依賴於成員變量,但不能說屬性就是成員變量,(好像也不是很直白...)而且屬性在代碼上能夠作到控制讀寫權限,而成員變量就不能夠了。
yii\base\BaseObject
。getter
或setter
函數,或二者都提供,用於訪問、修改上面提到的私有成員變量。 若是隻提供了getter
,那麼該屬性爲只讀屬性,只提供了setter
,則爲只寫。<?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