static 關鍵字在 PHP 中有兩種截然不同的用法:函數內靜態局部變量 與 類靜態成員。前者讓變量在函數調用間「保持記憶」,後者實現「類級別共享狀態」。本文系統梳理兩者語法、訪問方式、典型應用場景與常見誤區。
<?php
function counter() {
static $count = 0; // 僅初始化一次
$count++;
echo "調用次數: $count\n";
}
counter(); // 1
counter(); // 2
counter(); // 3
// $count 只存在於 counter() 作用域,但生命週期贯穿整個腳本運行
<?php
class Child {
public static $nums = 0; // 靜態屬性
public $name;
public function __construct($name) {
$this->name = $name;
}
public function join_game() {
self::$nums++; // 類內訪問:self::$屬性
echo "{$this->name} 加入遊戲\n";
}
}
// 類外訪問:類名::$屬性
$c1 = new Child('李逵'); $c1->join_game();
$c2 = new Child('張飛'); $c2->join_game();
$c3 = new Child('唐僧'); $c3->join_game();
echo "總人數: " . Child::$nums; // 3
<?php
class Util {
public static function greet(string $name): string {
return "Hello, $name";
}
}
echo Util::greet('PHP'); // 無需實例化
| 位置 | 靜態屬性 | 靜態方法 |
|---|---|---|
| 類內部 | self::$prop / static::$prop (晚期靜態綁定) | self::method() / static::method() |
| 子類覆蓋 | parent::$prop | parent::method() |
| 類外部 | ClassName::$prop | ClassName::method() |
| 實例對象 | $obj::$prop (可行但不推薦) | $obj::method() (可行但不推薦) |
<?php
class A {
public static function who() { echo __CLASS__; }
public static function test() { self::who(); } // 編譯期綁定 A
public static function testLSB() { static::who(); } // 運行期綁定調用類
}
class B extends A {
public static function who() { echo __CLASS__; }
}
A::test(); // A
B::test(); // A (self 綁定父類)
B::testLSB(); // B (static 綁定實際調用類 B)
global 或 $GLOBALS。private static $instance; private function __construct(){} public static function getInstance(){ if(!self::$instance) self::$instance=new self; return self::$instance; }public static readonly string $VERSION = '1.0'; 確保不可變性。理解靜態變量的「作用域 vs 生命週期」二維模型,能幫你在閉包緩存、單例、計數器、配置常量等場景寫出正確且高效的代碼。