| 表達式 | 本質 | unset 影響 | 作用域 |
| $GLOBALS['var'] | 超全局數組元素,**變量本身** | 銷毀變量本身,全局不可訪問 | 全腳本任何位置 |
| global $var | 創建指向 $GLOBALS['var'] 的**別名引用** | 僅銷毀局部別名,**原變量值保留** | 當前函數/作用域內 |
代碼驗證
案例一:unset($GLOBALS['var'])
<?php
$var1 = 1;
function test() {
unset($GLOBALS['var1']);
}
test();
echo $var1; // 無輸出 (變量已銷毀)
案例二:global $var; unset($var);
<?php
$var1 = 1;
function test() {
global $var1;
unset($var1); // 只銷毀局部引用
}
test();
echo $var1; // 輸出 1 (原值未變!)
底層機制解析
global $var 等價於 $var = &$GLOBALS['var'](引用賦值)。
- 函數內
unset($var) 斷開局部符號表與全局 zval 的綁定,**不觸發 zval 銷毀**(引用計數不為 0)。
unset($GLOBALS['var']) 直接從超全局數組移除元素,zval 引用計數歸零則被回收。
對比 C/C++ 全局變量
C 中全局變量在函數內默認可見(除非被局部同名遮蔽)。PHP 要求**顯式聲明 global** 才能在函數內訪問全局變量,減少誤修改風險。
$GLOBALS 超全局數組特性
- 自動包含所有全局作用域變量(鍵名為變量名)。
- 可在任何作用域直接讀寫:
$GLOBALS['x'] = 1;。
- 遞歸結構:
$GLOBALS['GLOBALS'] === $GLOBALS。
最佳實踐建議
- 極力避免全局變量:通過參數傳遞、依賴注入、單例/服務容器管理狀態。
- 必須使用時,**優先
$GLOBALS['name']** 明確語義,避免 global 隱式引用導致的難以追蹤的副作用。
- 絕不在函數內
unset($GLOBALS[...]),除非極其清楚後果(如框架核心清理階段)。
- 配置常量化:
define('CONFIG_KEY', 'val') 或 const CONFIG_KEY = 'val'; 替代全局變量。
- 舊代碼重構:逐步將
global $x 替換為參數注入。
常見誤區
- 以為
global $x 創建副本:錯誤,是引用別名。
- 以為
unset($x) 會清空全局值:錯誤,僅斷開局部綁定(見案例二)。
- 混淆
$GLOBALS 與 $_GLOBALS:不存在 $_GLOBALS,只有 $GLOBALS。
- 上一篇文章: PHP 判斷目錄/文件讀寫權限:is_writable 陷阱、空目錄遞歸檢測、實戰封裝函數
- 下一篇文章: PHP 兩層目錄遍歷查找指定文件:基於 Web 認證的掃描腳本(含 ASP 對比版)
Copyright ©
程式碼之家 All Rights Reserved