global是建立局部变量到全局变量的引用映射,非声明新变量;$globals是直接访问全局变量的超全局数组;二者均不适用于闭包和类方法,现代项目应避免使用global。

PHP 中 global 是用来“临时接入”全局变量的开关
它不声明新变量,也不改变作用域规则,只是让函数内部能读写已在全局作用域定义的变量。本质是建立一个局部变量名到全局变量的引用映射,不是复制值。
- 常见错误现象:
Notice: Undefined variable出现在函数里访问了本该全局的变量,但没加global - 使用场景:老项目中需在函数内修改配置、计数器、数据库连接句柄等跨函数共享的状态
- 参数差异:
global $a, $b;等价于$a =& $GLOBALS['a']; $b =& $GLOBALS['b'];,注意是引用赋值,改了就真改了 - 性能影响极小,但会让变量依赖隐式化,调试时容易漏看来源
不用 global 也能拿到全局变量?对,但得用 $GLOBALS
$GLOBALS 是 PHP 内置超全局数组,所有全局变量都作为键存在其中。它比 global 更直白,也更安全——至少你知道自己在动哪个全局变量。
- 常见错误现象:写了
global $config;却忘了在全局先定义$config = [];,结果函数里得到null或触发 notice - 使用场景:临时读取某个全局配置,不想污染当前作用域(比如只读不写)
- 示例:
echo $GLOBALS['db_host'] ?? 'localhost';比global $db_host; echo $db_host;更可控 - 兼容性:从 PHP 4 到 8.x 都稳定支持,
$GLOBALS不受strict_types影响
global 在闭包和类方法里完全失效
闭包默认隔离外部作用域,类方法则天然运行在对象作用域下,global 对这两者都不起作用。强行写只会静默失败或报错。
- 常见错误现象:在
array_map的匿名函数里写global $log_level;,结果变量还是未定义 - 正确做法:闭包用
use ($log_level)显式导入;类方法用$this->log_level或静态属性self::$log_level - 性能提示:用
use是值传递(默认)或引用传递(use (&$log_level)),比反复查$GLOBALS稍快 - 容易踩的坑:以为
global能穿透include文件边界——其实不能,每个文件有自己的全局作用域,include只是代码拼接,不是作用域合并
现代 PHP 项目基本不该用 global
它破坏封装、阻碍测试、掩盖依赖关系。Laravel、Symfony 这些框架连全局配置都通过容器注入,而不是靠 global 撒满代码。
立即学习“PHP免费学习笔记(深入)”;
- 替代方案:把需要共享的状态封装成类,用单例或依赖注入传入;配置走
.env+ 配置管理器 - 遗留代码处理:如果必须维护老系统,优先把
global替换为$GLOBALS访问,至少让变量名可见可搜 - 最麻烦的一点:
global声明必须出现在函数体开头附近,但很多人把它塞在 if 分支里,导致语法错误或逻辑错乱——PHP 不允许条件式声明全局变量











