php中全局变量需显式声明(global)或通过$globals访问,未定义变量不可用global创建,超全局变量如$_post只读,$_session需session_start(),现代项目应避免global以提升可维护性。

PHP函数里直接用外部变量会报 Notice: Undefined variable,不是语法错了,是作用域规则在起作用——必须显式接入,否则就当它是新变量。
global $var; 必须写在函数开头,且只对已存在的变量生效
很多人以为只要写了 global $config,函数里就能随便改 $config;其实它只是把当前函数作用域“挂载”到那个全局变量上,前提是 $config 在函数外已经定义过。
- 如果函数外没定义
$config,global $config不会自动创建,后续赋值也只是局部变量 - 支持一次声明多个:
global $a, $b, $db; - 不能用于动态变量名,比如
$key = 'user_id'; global $$key;会失败 - PHP 7.4+ 中,若全局变量是
readonly或来自const,global后也无法修改
$GLOBALS['var'] 不用声明,但拼错键名就静默失效
$GLOBALS 是数组,键是字符串(不含 $),所以 $GLOBALS['user_id'] 对,$GLOBALS['User_ID'] 或 $GLOBALS['$user_id'] 都不对——不会报错,只是读不到值。
- 适用于需要动态访问变量名的场景,比如
$GLOBALS[$key] = $val; - 修改数组元素要写全路径:
$GLOBALS['config']['host'] = '127.0.0.1';,不能只写$config['host'] = ...(除非已global $config) - 别对
$GLOBALS本身重新赋值,比如$GLOBALS = [];,这会断掉所有变量引用,后续$GLOBALS['x']和$x就不再同步
超全局变量($_GET、$_POST等)不用 global,但写操作有前提
$_GET、$_POST、$_SESSION 这些是 PHP 内置的超全局变量,任何地方都能读,但写不一定安全或有效。
-
$_POST和$_GET是只读副本,改了也没用,也不该改 -
$_SESSION必须先调用session_start()才能写,否则$_SESSION['token'] = 'abc'不生效 -
$_SERVER大部分字段只读,比如$_SERVER['REQUEST_URI']在 CLI 下根本不存在,直接取会触发 notice -
$_ENV默认为空,得看php.ini的variables_order是否含E,或手动putenv()设置过
现代项目里,global 和 $GLOBALS 应该尽量少用
它们不是语法缺陷,而是协作隐患:变量来源模糊、测试难 mock、并发下易状态污染(尤其 Swoole 或 CLI 长进程)。
- 参数传入比
global更清晰:function send_email($to, $config) { ... } - 配置统一走类或容器:
Config::get('mail.host'),而不是散落各处的$mail_config - 真要跨函数共享状态,优先用
static变量或类静态属性,比裸global更可控 - 如果非得用全局变量,至少命名带前缀(如
$APP_DEBUG)、文档写清生命周期、避免写操作
最容易被忽略的是:函数内用 global $x 后再对 $x 赋引用($x = &$y),会导致原全局变量脱离绑定——这个行为在 PHP 8 已明确不推荐,但老代码里还藏着。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











