在函式內部,變數預設為 動態 (區域) 變數:每次呼叫函式都會重新建立、初始化、銷毀。若需在多次呼叫間保持狀態,必須宣告為 靜態變數 (static)。本文以簡潔代碼對比兩者生命週期,並說明靜態變數的三大典型應用場景。
| 特性 | 動態變數 (預設) | 靜態變數 (static) |
|---|---|---|
| 儲存區 | 堆疊 | 資料段 / 靜態儲存區 |
| 初始化時機 | 每次呼叫函式 | 僅第一次呼叫執行初始化 |
| 銷毀時機 | 函式返回時 | 腳本結束 / 進程結束 |
| 值的保持 | 不保持 | 跨呼叫保持 |
| 作用域 | 函式內部 | 函式內部 (但生命週期全域) |
<?php
function dynamicCounter() {
$count = 0; // 動態變數
$count++;
echo "動態: $count\n";
}
function staticCounter() {
static $count = 0; // 靜態變數
$count++;
echo "靜態: $count\n";
}
echo "--- 呼叫 3 次 dynamicCounter ---\n";
dynamicCounter(); // 1
dynamicCounter(); // 1
dynamicCounter(); // 1
echo "--- 呼叫 3 次 staticCounter ---\n";
staticCounter(); // 1
staticCounter(); // 2
staticCounter(); // 3
?>
function getDbConnection() {
static $pdo = null;
if ($pdo === null) {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
}
return $pdo;
}
function fibonacci($n) {
static $cache = [0 => 0, 1 => 1];
if (isset($cache[$n])) return $cache[$n];
return $cache[$n] = fibonacci($n-1) + fibonacci($n-2);
}
function loadConfig($file) {
static $config = null;
if ($config === null) {
$config = parse_ini_file($file, true);
}
return $config;
}
| 特性 | 函式 static $var | 類別 static $prop |
|---|---|---|
| 可見性 | 僅函式內部 | 依 public/protected/private 控制 |
| 繼承行為 | 無繼承概念 | 父子類別共享同一儲存體 (Late Static Binding 影響存取) |
| 初始化語法 | 標量/陣列/常數表達式 | PHP 8.1+ 支援類型宣告與初始化 |
static 等於「常數」:靜態變數可修改,只是生命週期延長。private constructor。SplFixedArray 等無鎖結構。💡 一句話心法:函式裡的
static讓區域變數擁有「全域生命週期、區域可見性」——用來做「只初始化一次、多次複用」的私有倉庫最合適。