靜態變數僅存在於函數作用域,但生命週期贯穿整個腳本執行期間。一般區域變數在函數結束後釋放,而宣告為 static 的變數會保留上次的值。
<?php
function test() {
static $nm = 0;
$nm = $nm * 2 + 1;
print $nm . "<br />";
}
test(); // 輸出 1
test(); // 輸出 3
test(); // 輸出 7
?>
每次呼叫 test(),$nm 都保留上一次運算結果。
屬於類別本身,不屬於特定實例。所有實例共享同一份靜態屬性。透過 類別名::$屬性 或 self::$屬性 存取。
<?php
class NowaMagic {
public static $nm = 'www.nowamagic.net';
public function nmMethod() {
return self::$nm;
}
}
class Article extends NowaMagic {
public function articleMethod() {
return parent::$nm;
}
}
echo NowaMagic::$nm; // 直接存取
$obj = new NowaMagic();
echo $obj->nmMethod(); // 透過實例方法存取
echo Article::$nm; // 子類別繼承
$art = new Article();
echo $art->nmMethod(); // 子類別實例方法存取
?>
同樣屬於類別,透過 類別名::方法() 呼叫。內部使用 self:: 存取靜態成員,$this 不可用於靜態方法。
PHP 無原生靜態建構子,可在類別定義後立即呼叫初始化方法:
<?php
function Demonstration() { return 'Demo result'; }
class MyStaticClass {
public static $MyStaticVar = null;
public static function MyStaticInit() {
self::$MyStaticVar = Demonstration();
}
}
MyStaticClass::MyStaticInit();
echo MyStaticClass::$MyStaticVar;
?>
PHP 允許在函數內部宣告靜態變數,C# 則限於類別層級。PHP 函數為一等公民,函數靜態變數可避免全域變數污染。
:: 呼叫靜態成員(ClassName::method()),不可用 ->。self::$var,靜態方法用 self::method()。PHP 5.3+ 引入 static:: 關鍵字實現晚期靜態綁定,依實際調用類別解析:
<?php
class ParentClass {
public static function who() { echo 'Parent'; }
public static function test() { static::who(); } // LSB
}
class ChildClass extends ParentClass {
public static function who() { echo 'Child'; }
}
ChildClass::test(); // 輸出 Child
?>
若使用 self::who() 則永遠輸出 Parent。parent:: 可明確呼叫父類別成員。
PHP 的 static 提供比 C# 更靈活的機制(函數靜態變數、晚期靜態綁定、可覆寫靜態成員),但靈活性也帶來複雜度。善用 self::、parent::、static:: 三者差異,能寫出更具擴充性的程式碼。