在 PHP 中,類別成員變數也稱為屬性。這些變數是類別定義的一部分,用於表示類別實例的狀態(即,區分一個類別實例與另一個類別實例)。在實務中,您可能經常希望以特殊方式處理屬性的讀取或寫入。例如,您可能希望在將字串指派給 label
屬性時,始終修剪字串。您可以使用以下程式碼來達成此任務
$object->label = trim($label);
上述程式碼的缺點是,您必須在程式碼中所有可能設定 label
屬性的地方呼叫 trim()
。如果將來 label
屬性有新的需求,例如第一個字母必須大寫,您又必須修改每一段指派值給 label
的程式碼。程式碼的重複會導致錯誤,這是您希望盡可能避免的做法。
為了解決這個問題,Yii 引入了一個名為 yii\base\BaseObject 的基底類別,它支援基於 getter 和 setter 類別方法定義屬性。如果一個類別需要該功能,它應該從 yii\base\BaseObject 或子類別繼承。
資訊:Yii 框架中幾乎每個核心類別都從 yii\base\BaseObject 或子類別繼承。這表示,每當您在核心類別中看到 getter 或 setter 時,您都可以像屬性一樣使用它。
getter 方法是以單字 get
開頭的方法;setter 方法以 set
開頭。get
或 set
字首後面的名稱定義了屬性的名稱。例如,getter getLabel()
和/或 setter setLabel()
定義了一個名為 label
的屬性,如下面的程式碼所示
namespace app\components;
use yii\base\BaseObject;
class Foo extends BaseObject
{
private $_label;
public function getLabel()
{
return $this->_label;
}
public function setLabel($value)
{
$this->_label = trim($value);
}
}
為了清楚起見,getter 和 setter 方法建立了屬性 label
,在本例中,它在內部引用了一個名為 _label
的私有屬性。
由 getter 和 setter 定義的屬性可以像類別成員變數一樣使用。主要區別在於,當讀取此類屬性時,將呼叫相應的 getter 方法;當將值指派給屬性時,將呼叫相應的 setter 方法。例如
// equivalent to $label = $object->getLabel();
$label = $object->label;
// equivalent to $object->setLabel('abc');
$object->label = 'abc';
由沒有 setter 的 getter 定義的屬性是唯讀的。嘗試將值指派給此類屬性將導致 InvalidCallException。同樣地,由沒有 getter 的 setter 定義的屬性是唯寫的,嘗試讀取此類屬性也會導致例外。擁有唯寫屬性並不常見。
對於透過 getter 和 setter 定義的屬性,有幾個特殊的規則和限制
$object->label
和 $object->Label
是相同的。這是因為 PHP 中的方法名稱不區分大小寫。Foo
類別有一個成員變數 label
,那麼指派 $object->label = 'abc'
將影響成員變數 label
;該行不會呼叫 setLabel()
setter 方法。property_exists()
無法判斷魔術屬性。您應該分別呼叫 canGetProperty() 或 canSetProperty()。回到本指南開頭描述的問題,現在只需在 setter setLabel()
中調用 trim()
,而不是在指派 label
值的所有地方都調用 trim()
。如果新的需求使得標籤必須在最初大寫,則可以快速修改 setLabel()
方法,而無需觸及任何其他程式碼。這一個變更將普遍影響對 label
的每次指派。
發現錯字或您認為此頁面需要改進?
在 github 上編輯它 !
註冊 或 登入 以發表評論。