理解 static 成員在記憶體中的真實存放位置,是避免「修改一處、全局生效」等經典 Bug 的關鍵。本文通過 print_r() 實測,直觀展示靜態屬性與實例屬性的本質區別。
new 操作在「物件」記憶體中獨立分配。<?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);
// 輸出:Human Object ( [height] => ) ← 只有 height,沒有 name!
$p1::$name = "夫人"; // ② 通過物件修改靜態屬性
echo $p2::$name; // 輸出:夫人 ← p2 也變了!
?>
Human::$name 在腳本加載階段就已分配記憶體,與是否 new 無關。print_r($p1) 僅顯示 height,證明 name 不在物件結構體中。$name,影響所有後續讀取。無論 static function 還是普通 function,其機器碼都只在類定義時載入一次。new 出來的物件僅持有屬性數據,方法調用通過類的虛函數表分發。這也是為何 print_r($obj) 永遠不會列出方法。
unset 或設為 null 釋放。