掌握 static 關鍵字在 PHP 中的記憶體模型與調用規則,是寫出高效、無 Bug 物件導向代碼的基石。本文從底層記憶體佈局切入,系統梳理靜態成員的存取邏輯、常見陷阱與最佳實踐。
非靜態屬性隨每個實例獨立分配記憶體;而 靜態屬性、靜態方法、普通方法在記憶體中僅存在一份,歸屬於類本身,不依賴具體物件。這決定了它們的調用方式必須通過「類名::成員」或「self::成員」,而非 $this->。
<?php
class Human {
static public $name = "小妹";
public $height = 180;
static public function tell() {
echo self::$name; // ✅ 靜態方法訪問靜態屬性
// echo $this->height; // ❌ 錯誤:靜態方法無 $this 上下文
}
public function say() {
echo self::$name . "我說話了"; // ✅ 普通方法訪問靜態屬性
echo $this->height; // ✅ 普通方法訪問非靜態屬性
}
}
$p1 = new Human();
$p1->say(); // 物件調用普通方法
$p1->tell(); // 物件調用靜態方法(允許但不推薦)
echo $p1::$name; // 物件訪問靜態屬性(語法糖,本質仍是 Human::$name)
// Human::say(); // ❌ PHP 5.4+ 會報錯:非靜態方法不能靜態調用
?>
| 調用者 \ 被調用 | 靜態屬性 | 非靜態屬性 | 靜態方法 | 非靜態方法 |
|---|---|---|---|---|
| 類名:: | ✅ | ❌ | ✅ | ❌ (5.4+嚴格模式) |
| 物件-> | ✅ (語法糖) | ✅ | ✅ (不推薦) | ✅ |
| self:: (類內部) | ✅ | ❌ | ✅ | ✅ (自動轉為靜態調用) |
當在類內部使用 self::nonStaticMethod() 時,PHP 會將該方法視為靜態調用,導致方法內無法使用 $this。這在早期版本常被濫用作「偽靜態調用」,現代開發應避免此模式,改用實例調用或重構為真正的靜態方法。
$this 或非靜態成員。ClassName::member 而非 $obj::member,語義更清晰。