global仅在函数内建立对已存在全局变量的引用映射,不创建新变量;必须先在文件顶层定义(如$config = []),否则触发Undefined variable错误,且不能跨文件、不能用于类方法或闭包。

global 关键字本身不危险,危险的是它让函数隐式依赖外部状态——你改了全局变量,所有用它的函数都可能意外行为改变,而且根本查不到谁动的手。
global $x; 声明无效的真正原因
不是语法错了,而是 $x 根本没在函数外定义过。PHP 的 global 不创建变量,只建立引用映射。如果外面没写 $x = null; 或类似初始化,函数里一用 global $x; 就触发 Notice: Undefined variable。
- 必须先在文件顶层(或
require的配置文件中)定义变量,哪怕只是$config = []; -
global不能跨文件生效:在函数里include 'config.php',里面定义的$db_host仍是局部变量,global $db_host也拉不进来 - 不能用于表达式:
global ${'user_id'}是语法错误,只能是纯变量名
为什么改了 global 变量,类方法里读不到
因为 global 只连接当前脚本的“顶层作用域”,不是全项目全局。类的方法运行在对象作用域下,和文件顶层是隔离的。哪怕你在同一个文件顶部写了 $log_level = 'debug';,类里的 public function handle() { echo $log_level; } 依然报错。
- 类中要访问同名全局变量,必须在每个方法里单独写
global $log_level; - 更可靠的做法是用静态属性:
self::$log_level,或通过构造函数注入 -
$GLOBALS['log_level']虽然能跨作用域读取,但键名拼错不会报错,只返回null或触发Undefined index
global + static 混用是典型内存陷阱
常见写法:static $cache; global $data; if (!$cache) $cache = $data;。第一次执行后,$cache 就是 $data 的副本值,后续 $data 被修改,$cache 完全无感——它早就和 $data 脱钩了。
立即学习“PHP免费学习笔记(深入)”;
- 对数组或对象做赋值(
$cache = $data;)会切断引用,变成独立副本 - 想保持同步?得每次重新读:
if (!isset($GLOBALS['config'])) { /* 加载 */ } - 别把
$pdo这类资源句柄存进static,连接可能被其他地方关闭,下次用就 fatal error
CLI 和 Web 下 global 变量不会跨请求保留
每次 HTTP 请求或 CLI 执行都是全新进程,全局变量从头初始化。你以为的“持久化计数器”其实每请求重置一次。
- 想跨请求共享数据?用 Redis、数据库或 session,别靠
global $counter; - 测试时容易误判:本地跑一次没问题,压测时多个并发改同一个
global $cache,结果互相覆盖 - 单元测试难 mock:写
global $db;的函数,你得在每个 test case 前手动设$db = $mock;,而传参只需构造函数塞进去
最麻烦的不是语法限制,是你永远没法一眼看出一个函数到底依赖哪些外部变量——它们散落在文件各处,没有类型提示,没有 IDE 跳转,只有 grep global 硬翻。现代 PHP 项目基本该把它当技术债处理,而不是默认选项。



















