PHP static 關鍵字用於定義靜態屬性、靜態方法與函數內靜態變量。本文系統性解析靜態成員的訪問規則(self::/parent::/類名::/對象->)、非靜態方法靜態調用條件、靜態變量在函數與遞歸中的生命週期特性,並提供完整代碼驗證範例。
| 訪問方式 | 靜態屬性/方法 | 非靜態屬性/方法 | 前提條件 |
|---|---|---|---|
類名::member | ✅ 支援 | ✅ 支援 | 非靜態方法:不可使用 $this、不可調用非靜態成員 |
self::member | ✅ 支援 | ❌ 不支援 | 僅類內部使用,指向當前類(非晚期靜態綁定) |
parent::member | ✅ 支援 | ✅ 支援 | 子類訪問父類,同非靜態限制 |
$obj->member | ✅ 支援(方法) | ✅ 支援 | 需實例化對象,靜態屬性不建議此方式 |
static::member | ✅ 支援 | ✅ 支援 | PHP 5.3+ 晚期靜態綁定 (LSB),指向實際調用類 |
<?php
class Person {
// 靜態屬性
public static $country = "中國";
// 靜態方法
public static function myCountry() {
echo "我是 " . self::$country . " 人<br/>"; // 類內部用 self::
}
}
class Student extends Person {
function study() {
echo "我是 " . parent::$country . " 人<br/>"; // 子類訪問父類用 parent::
}
}
// 外部訪問:類名::
echo Person::$country . "<br/>"; // 輸出:中國
Person::myCountry(); // 輸出:我是中國人
// 物件訪問靜態方法(可行但不推薦)
$p1 = new Person();
$p1->myCountry(); // 輸出:我是中國人
// 子類繼承靜態成員
echo Student::$country . "<br/>"; // 輸出:中國
$t1 = new Student();
$t1->study(); // 輸出:我是中國人
?>
中國
我是中國人
我是中國人
中國
我是中國人
self::$property、self::method()parent::$property、parent::method()ClassName::$property、ClassName::method()$obj->staticMethod()(但無 $this 上下文)static::$property 解決繼承中 self:: 綁定過早問題<?php
function foo() {
static $int = 0; // ✅ 正確:字面值初始化
// static $int = 1 + 2; // ❌ 錯誤:表達式不允許
// static $int = sqrt(121); // ❌ 錯誤:函數呼叫不允許
$int++;
echo $int . "<br/>";
}
foo(); // 1
foo(); // 2
foo(); // 3
// 靜態變量僅初始化一次,後續調用保持上次值
?>
<?php
function Test() {
static $w3sky = 0;
echo $w3sky . "<br/>";
$w3sky++;
}
Test(); // 0
Test(); // 1
Test(); // 2
// 每次調用輸出遞增值
?>
<?php
function Test() {
static $count = 0;
$count++;
echo $count . "<br/>";
if ($count < 10) {
Test(); // 遞歸調用
}
$count--; // 回溯時遞減(演示用,實際遞歸通常不需此步)
}
Test();
// 輸出 1 到 10,靜態變量跨遞歸層級共享
?>
| 特性 | 函數靜態變量 | 全域變量 | 類靜態屬性 |
|---|---|---|---|
| 作用域 | 僅所在函數內可見 | 全域可見(需 global) | 類作用域內,外部可用 類名:: 訪問 |
| 生命週期 | 腳本執行期間持久 | 腳本執行期間持久 | 腳本執行期間持久 |
| 初始化 | 首次執行到達時一次 | 定義時 | 類定義時 |
| 封裝性 | 高(隱藏在函數內) | 低(污染全域命名空間) | 中(屬於類) |
| 遞歸安全 | 天然共享,適合計數 | 需小心衝突 | 需實例化或靜態調用 |
static:: 而非 self::精通 static 機制,能寫出更高效、封裝性更強的 PHP 代碼,並避開繼承與遞歸中的常見陷阱。