php函数有独立作用域,无法直接读取全局变量;需用global、$globals或传参解决;匿名函数用use捕获外部变量;static变量在多次调用间保持值;include不创建新作用域,易致变量污染。

函数内部不能直接读取全局变量
PHP 的函数有独立作用域,定义在函数外面的变量,默认进不去函数体内。这不是 bug,是设计使然——避免意外污染和命名冲突。
常见错误现象:Undefined variable 警告,或者函数返回空值、默认值,但你明明在外面赋了值。
- 用
global显式声明(仅限普通变量,不适用于超全局数组如$_POST) - 用
$GLOBALS数组间接访问,比如$GLOBALS['username'] - 更推荐:把值作为参数传进去,函数保持纯逻辑,不依赖外部状态
示例:
$name = 'Alice';
function sayHello() {
echo $name; // Notice: Undefined variable
}
sayHello();
use 关键字只对匿名函数有效
闭包(function () use ($x) { ... })才能用 use 捕获外部变量。普通函数不支持 use,写了会直接报语法错误 Parse error: syntax error。
使用场景:回调、事件处理器、需要“记住”当前上下文的地方,比如循环中绑定不同参数。
立即学习“PHP免费学习笔记(深入)”;
-
use默认按值传递,加&才能引用传入,后续修改会影响原变量 - 不能在
use里写表达式,只能是变量名或带&的变量名 - 如果用了
use却没列出某个外部变量,它依然不可见——不会自动继承
示例:
$prefix = 'Mr.';
$greet = function ($n) use ($prefix) {
return $prefix . ' ' . $n;
};
静态变量在函数调用间保持值
static 变量不是全局的,也不属于类,而是“绑定在函数上”的私有状态。第一次调用初始化,之后每次调用都复用上次的值。
容易踩的坑:误以为 static 是线程安全或跨请求共享——它只在单次请求的同一函数多次调用中有效,PHP-FPM 或 CLI 下行为一致,但绝不跨请求。
- 初始化表达式只执行一次,即使写成
static $i = time();,也只在首次调用时求值 - 不能用函数调用、变量或常量做初始值(除非 PHP 8.1+ 支持 const 表达式)
- 调试时注意:var_dump 函数内
static变量,看到的是当前累积值,不是“重置后”的
示例:
function counter() {
static $count = 0;
$count++;
return $count;
}
echo counter(); // 1
echo counter(); // 2
include/require 引入的文件不创建新作用域
这是最隐蔽的作用域混淆点:include 'config.php' 后,里面定义的变量、函数会直接“冒泡”到当前作用域,和手写在当前位置效果一样。
后果很实际:变量名冲突、意外覆盖、调试时找不到定义位置。
- 不要在被 include 的文件里直接写
$db_host = '...';,改用return ['host' => '...'];然后$config = include 'config.php'; - 函数定义不受影响,但重复
include同一文件会导致Cannot redeclare function -
require_once和include_once只解决重复加载问题,不解决作用域污染
错误示范:include 'settings.php'; // 里面写了 $api_key = 'xxx'; —— 现在它就在你函数外面裸奔了











