首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 變數作用域完整解析:靜態、動態、全域、區域與變數函數

     編輯:PHP 相關知識

前言

變數作用域決定了變數「在哪裡可見、何時銷毀」。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 檔案間)。兩種宣告方式:

方式 1: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; // 錯誤:未定義
?>

方式 2:$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()呼叫時函數定義處動態派發、回調、策略模式

最佳實踐建議

  1. 優先使用區域變數:減少副作用、易於測試、避免命名衝突。
  2. 慎用全域變數:若需共享狀態,考慮依賴注入、單例、或傳遞物件/陣列參數。
  3. 善用 static 快取:遞迴、昂貴計算、單例模式初始化。
  4. 避免 global 污染:改用 $GLOBALS['key'] 明確標示全域存取。
  5. 變數函數驗證:呼叫前用 is_callable($var) 檢查,防止錯誤。

結語

PHP 變數作用域機制簡單但威力強大。掌握 static、global、$GLOBALS、變數函數的差異與適用場景,能讓程式碼更清晰、效能更佳、Bug 更少。記住:最小作用域原則 是良好設計的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved