static 靜態屬性的記憶體位置在類別中,而非物件實例中。 同理,無論靜態或非靜態方法,程式碼段均位於類別記憶體空間,僅有一份副本。
<?php
header("content-type:text/html;charset=utf-8");
class Human {
static public $name = "小妹";
public $height;
public function tell() {}
}
echo Human::$name; // 類別定義完成即存在,不依賴物件
$p1 = new Human();
$p2 = new Human();
print_r($p1); // 僅顯示 height 屬性,無 name
$p1::$name = "夫人"; // 透過 p1 修改靜態屬性
echo $p2::$name; // 輸出「夫人」——p2 同步變化
?>
echo Human::$name 成功:類別載入完成即在類別空間分配靜態屬性,無需實例化。print_r($p1) 無 name:物件實例內存僅含非靜態屬性(height),靜態屬性不在物件中。$p1::$name 後 $p2::$name 同步變化:所有實例共享類別空間中的同一份靜態屬性。同樣建立物件並 print_r($obj),結果不會列出任何方法(無論 static 或非 static),證明方法程式碼同樣位於類別空間,不佔用物件實例記憶體。
| 成員類型 | 記憶體位置 | 副本數量 | 存取方式 |
|---|---|---|---|
| 靜態屬性 | 類別空間 | 1 份(全域共享) | 類別名::屬性名 / 物件::屬性名 |
| 非靜態屬性 | 物件實例 | 每實例 1 份 | $this->屬性名 / $obj->屬性名 |
| 靜態方法 | 類別空間(程式碼段) | 1 份 | 類別名::方法名 / 物件::方法名 |
| 非靜態方法 | 類別空間(程式碼段) | 1 份 | $this->方法名 / $obj->方法名 |
理解記憶體模型,即可自然推導出所有存取規則與限制。