php 8.1 中 $globals 是只读快照,禁止整体赋值(如 $globals = []),允许单键写入但不保证同步更新原变量,修改全局变量应直接赋值(如 $var = 42)或用 global 关键字。

$GLOBALS 在 PHP 8.1 中只能读,不能写整个数组 —— 这是核心限制,不是 bug,是设计变更。
PHP 8.1 起 $GLOBALS 是只读副本
从 PHP 8.1.0 开始,$GLOBALS 不再是全局符号表的可写引用,而是它的只读快照。你仍能用 $GLOBALS['var_name'] 读取值,但任何试图修改整个数组的行为都会触发致命错误(Fatal error)。
-
$GLOBALS = []→ Fatal error: Cannot assign to $GLOBALS -
$GLOBALS += ['x' => 1]→ 同样报错 -
unset($GLOBALS['foo'])→ 允许(删除的是副本,不影响真实变量) -
$GLOBALS['foo'] = 'new'→ 允许(这是对单个键的写入,PHP 8.1 仍支持)
修改全局变量必须直接赋值,不能靠 $GLOBALS['x'] = ...
以前(PHP 8.0 及更早)通过 $GLOBALS['x'] = 'y' 能间接改掉全局变量 $x;现在这种写法虽不报错,但不再保证同步更新原始变量——尤其在涉及引用、对象或复杂类型时行为不可靠。
- 安全做法:想改全局变量
$count,就直接写$count = 42; - 危险写法:用
$GLOBALS['count'] = 42;—— 它可能“看起来生效”,但实际未影响符号表,后续调用可能拿到旧值 - 例外:标量变量(string/int/bool)在简单场景下仍能 work,但不推荐依赖
global 关键字和 $GLOBALS 的本质区别没变,但风险更高了
global $x 是在函数内创建 $x 对外部变量的别名;$GLOBALS['x'] 曾经是直接访问变量本身。PHP 8.1 后,后者退化为“只读优先”的间接访问,而前者依然稳定可靠。
- 需要在函数里改全局
$config?用global $config; $config = [...]; - 只是读取?
$GLOBALS['config']或global $config; echo $config;都可以 - 不要混用:
global $x; $GLOBALS['x'] = 'bad';容易引发状态不一致
调试时打印 $GLOBALS 仍然有用,但别信它能反映实时符号表
print_r($GLOBALS) 或 var_dump($GLOBALS) 还能帮你快速查看当前有哪些全局变量,但它输出的是快照,不是活引用。
- 新增全局变量(如
$debug_mode = true;)后,$GLOBALS里立刻可见 - 但如果你用
unset($GLOBALS['old']),只是删了副本,$old依然存在且可访问 - 真正删全局变量要用
unset($old),而不是动$GLOBALS
最易被忽略的一点:PHP 8.1 的这个变更不是“禁止所有写操作”,而是禁掉了对数组整体的写,同时弱化了单个键写入的语义保证。真要维护全局状态,老老实实操作变量名本身,别绕路。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











