變數作用域決定了變數「在哪裡可見、何時銷毀」。PHP 有五種主要變數類型:靜態變數、動態(區域)變數、全域變數、區域變數、變數函數。理解它們的生命週期與可視範圍,是撰寫無 Bug 程式的基礎。
static特性:函數結束後**不釋放記憶體**,下次呼叫保留上次的值。適用於計數器、快取、遞迴狀態保存。
<?php
function counter() {
static $count = 0; // 僅初始化一次
echo "呼叫次數:" . ++$count . "<br>";
}
counter(); // 1
counter(); // 2
counter(); // 3
?>
記憶體圖解:
特性:函數內宣告,函數結束即銷毀。每次呼叫重新初始化。預設所有函數內變數皆為區域變數。
<?php
function demo() {
$i = 0;
echo $i++ . "<br>"; // 每次都輸出 0
}
demo(); // 0
demo(); // 0
?>
global / $GLOBALS特性:腳本任何位置可見(函數內外、include 檔案間)。兩種宣告方式:
global $var(函數內引入)<?php
$a = 1;
$b = 2;
function test() {
global $a, $b; // 引入全域變數
echo "函數內 a=$a, b=$b<br>"; // 1, 2
$a = 10; // 修改會影響外部
$c = 100; // 未宣告 global,仍為區域變數
}
test();
echo "函數外 a=$a, b=$b<br>"; // 10, 2
// echo $c; // 錯誤:未定義
?>
$GLOBALS['var'](超全域陣列,無需宣告)<?php
$x = 5;
function foo() {
$GLOBALS['x'] = 20; // 直接修改
$GLOBALS['y'] = 30; // 建立新全域變數
}
foo();
echo $x; // 20
echo $y; // 30
?>
差異:global 建立別名(引用),$GLOBALS 直接操作陣列元素。$GLOBALS 在靜態分析、動態變數名時更方便。
函數內宣告、未加 global/static 的變數即為區域變數。函數外的變數在函數內**不可見**,反之亦然。
<?php
$a2 = 10; // 全域
function fun() {
$a1 = 5; // 區域
echo $a2; // 無輸出($a2 在此不可見)
}
fun();
echo $a1; // 錯誤:$a1 僅在 fun() 內存在
?>
輸出結果:無任何輸出($a2 在函數內為 null,$a1 在函數外未定義)。
當變數後加 (),PHP 會尋找同名函數並執行。適用於回調、策略模式、動態調度。
<?php
function greet($name) {
echo "Hello, $name!<br>";
}
function bye($name) {
echo "Goodbye, $name!<br>";
}
$action = 'greet';
$action('Alice'); // 等同 greet('Alice')
$action = 'bye';
$action('Bob'); // 等同 bye('Bob')
// 陣列映射動作
$actions = ['morning' => 'greet', 'night' => 'bye'];
$actions['morning']('Charlie'); // Hello, Charlie!
?>
注意:變數函數無法直接呼叫語言結構(如 echo()、isset()、unset()),需包裝成函數。
static 結合遞迴的實用模式<?php
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);
}
for ($i = 0; $i < 10; $i++) {
echo fibonacci($i) . " ";
}
// 輸出:0 1 1 2 3 5 8 13 21 34
?>
| 類型 | 關鍵字 | 生命週期 | 可視範圍 | 典型用途 |
|---|---|---|---|---|
| 靜態 | static | 腳本執行期間 | 宣告的函數內 | 計數器、快取、遞迴狀態 |
| 區域/動態 | (預設無) | 函數呼叫期間 | 宣告的函數內 | 暫存計算、迴圈變數 |
| 全域 | global / $GLOBALS | 腳本執行期間 | 全腳本(含 include) | 設定值、資料庫連線、共享狀態 |
| 超全域 | $GLOBALS, $_GET, $_POST... | 請求期間 | 任何位置 | 輸入資料、伺服器資訊、Session |
| 變數函數 | $var() | 呼叫時 | 函數定義處 | 動態派發、回調、策略模式 |
static 快取:遞迴、昂貴計算、單例模式初始化。global 污染:改用 $GLOBALS['key'] 明確標示全域存取。is_callable($var) 檢查,防止錯誤。PHP 變數作用域機制簡單但威力強大。掌握 static、global、$GLOBALS、變數函數的差異與適用場景,能讓程式碼更清晰、效能更佳、Bug 更少。記住:最小作用域原則 是良好設計的基石。