W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
在 PHP 中,類的成員變量也被稱為屬性(properties)。它們是類定義的一部分,用來表現(xiàn)一個實例的狀態(tài)(也就是區(qū)分類的不同實例)。在具體實踐中,常常會想用一個稍微特殊些的方法實現(xiàn)屬性的讀寫。例如,如果有需求每次都要對?label
?屬性執(zhí)行 trim 操作,就可以用以下代碼實現(xiàn):
$object->label = trim($label);
上述代碼的缺點是只要修改?label
?屬性就必須再次調(diào)用?trim()
?函數(shù)。若將來需要用其它方式處理?label
?屬性,比如首字母大寫,就不得不修改所有給?label
?屬性賦值的代碼。這種代碼的重復會導致 bug,這種實踐顯然需要盡可能避免。
為解決該問題,Yii 引入了一個名為 yii\base\Object 的基類,它支持基于類內(nèi)的?getter?和?setter(讀取器和設定器)方法來定義屬性。如果某類需要支持這個特性,只需要繼承 yii\base\Object 或其子類即可。
補充:幾乎每個 Yii 框架的核心類都繼承自 yii\base\Object 或其子類。這意味著只要在核心類中見到 getter 或 setter 方法,就可以像調(diào)用屬性一樣調(diào)用它。
getter 方法是名稱以?get
?開頭的方法,而 setter 方法名以?set
?開頭。方法名中?get
?或?set
?后面的部分就定義了該屬性的名字。如下面代碼所示,getter 方法?getLabel()
?和 setter 方法?setLabel()
?操作的是?label
?屬性,:
namespace app\components;
use yii\base\Object;
class Foo extend Object
{
private $_label;
public function getLabel()
{
return $this->_label;
}
public function setLabel($value)
{
$this->_label = trim($value);
}
}
(詳細解釋:getter 和 setter 方法創(chuàng)建了一個名為?label
?的屬性,在這個例子里,它指向一個私有的內(nèi)部屬性?_label
。)
getter/setter 定義的屬性用法與類成員變量一樣。兩者主要的區(qū)別是:當這種屬性被讀取時,對應的 getter 方法將被調(diào)用;而當屬性被賦值時,對應的 setter 方法就調(diào)用。如:
// 等效于 $label = $object->getLabel();
$label = $object->label;
// 等效于 $object->setLabel('abc');
$object->label = 'abc';
只定義了 getter 沒有 setter 的屬性是只讀屬性。嘗試賦值給這樣的屬性將導致 yii\base\InvalidCallException (無效調(diào)用)異常。類似的,只有 setter 方法而沒有 getter 方法定義的屬性是只寫屬性,嘗試讀取這種屬性也會觸發(fā)異常。使用只寫屬性的情況幾乎沒有。
通過 getter 和 setter 定義的屬性也有一些特殊規(guī)則和限制:
$object->label
?和?$object->Label
?是同一個屬性。因為 PHP 方法名是不區(qū)分大小寫的。Foo
?類有個?label
?成員變量,然后給?$object->label = 'abc'
?賦值,將賦給成員變量而不是 setter?setLabel()
?方法。回到開頭提到的問題,與其處處要調(diào)用?trim()
?函數(shù),現(xiàn)在我們只需在 setter?setLabel()
?方法內(nèi)調(diào)用一次。如果 label 首字母變成大寫的新要求來了,我們只需要修改setLabel()
?方法,而無須接觸任何其它代碼。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: