$GLOBALS 是超全局数组,直接操作全局变量本体;global 是关键字,创建别名引用,unset 或引用赋值后会脱离全局变量。

PHP 中 $GLOBALS 和 global 的本质区别
二者根本不是“写法不同”,而是完全不同的机制:$GLOBALS 是一个真实存在的超全局数组,直接映射到全局作用域的变量本身;global 是一个关键字,仅在函数内起作用,它创建的是对全局变量的**别名引用**(alias),不是指针,也不是副本。
这意味着:
— 修改 $GLOBALS['foo'] 就是修改全局变量 $foo 本体;
— 修改 global $foo; $foo = ... 初期确实影响全局变量,但一旦你对 $foo 做了引用赋值(如 $foo = &$bar),这个别名就断开了,后续操作只影响局部别名,不再波及全局。
unset() 行为差异最能暴露问题
这是最容易踩坑的地方:用 unset() 删除变量时,global 和 $GLOBALS 的效果完全不同。
-
global $x; unset($x);→ 只销毁函数内的别名,全局$x依然存在 -
unset($GLOBALS['x']);→ 直接从全局作用域中删除$x,之后访问会触发Notice: Undefined variable
示例验证:
$x = 'alive';
function f1() {
global $x;
unset($x);
}
function f2() {
unset($GLOBALS['x']);
}
f1();
echo $x; // 输出 'alive'
f2();
echo $x; // Notice: Undefined variable: x
引用赋值(&)会让 global 别名失效
这是最隐蔽也最常被忽略的陷阱。只要在函数内对 global 声明的变量做引用赋值,它就立刻脱离全局变量,变成独立局部变量。
常见错误场景:
-
global $a, $b; $b = &$a;→ 此后修改$b不再影响全局$b,只影响$a -
$GLOBALS['b'] = &$GLOBALS['a'];→ 全局$b和$a真实绑定,后续任一修改都同步
所以,如果你需要在函数内建立或切换变量间的引用关系,并希望影响全局状态,必须用 $GLOBALS,不能依赖 global。
何时该用哪个?看意图是否要穿透作用域
选择依据不是“哪个更短”,而是“你是否需要操作变量本体”:
- 只需要读/写全局变量值,且不涉及引用、unset、动态变量名 →
global $var足够,语义清晰 - 需要 unset 全局变量、动态构造变量名(如
$name = 'user_' . $id; $GLOBALS[$name] = ...)、或确保引用关系始终绑定全局 → 必须用$GLOBALS['var'] - 跨函数共享状态、调试时检查所有全局变量 →
print_r($GLOBALS)直接可用;global无法做到
最后提醒一句:PHP 的 $GLOBALS 数组包含所有已声明的全局变量(包括函数、类定义等符号),但它不包含通过 global 在函数内声明的别名变量 —— 那些只是临时映射,不会出现在 $GLOBALS 键中。


















