
php中用&符号创建变量引用
PHP里创建变量引用,核心就一个操作符:&。它不是取地址,而是让两个变量指向同一块内存,修改任一变量,另一方立刻可见。
常见错误是把&当成“复制”或“别名声明”,其实它是运行时绑定——一旦被引用的变量被unset(),引用变量仍存在,但变成未定义状态(读取会触发Notice: undefined variable)。
-
$a = 10; $b = &$a;—— 正确:$b 是 $a 的引用 -
$b = &10;—— 错误:不能对字面量取引用 -
$b = &$a + 1;—— 错误:表达式结果不可引用,PHP 7.4+ 直接报Fatal Error: Cannot assign by reference to overloaded Object类似错误 - 函数返回值需显式支持引用:函数定义必须有
&,调用时也得加&,缺一不可
函数返回引用时必须双&:定义和调用都要写
PHP 不允许隐式引用返回,哪怕函数内部用了&,调用时不加,得到的仍是副本。这是最容易漏掉的一环。
典型场景:封装一个可修改的配置容器,或实现链式调用中的状态共享。
立即学习“PHP免费学习笔记(深入)”;
- 定义:
function &get_config() { Static $cfg = []; return $cfg; } - 调用:
$c = &get_config();—— 必须带&,否则$c只是副本 - 漏掉
&会导致后续修改$c不影响原始$cfg,调试时发现“改了没生效”,大概率卡在这儿 - PHP 8.1+ 对未加
&调用引用函数会发Deprecated警告,但默认不显示,需开启E_DEPRECATED
数组元素引用要小心foreach的自动解引用
在foreach里用&$v遍历数组,循环结束后若不unset($v),$v 仍持有对最后一个元素的引用,可能意外修改原数组。
这不是 bug,是设计行为,但极易引发隐蔽逻辑错误,尤其在多次遍历或函数复用时。
-
$arr = [1,2,3]; foreach ($arr as &$v) { $v *= 2; } unset($v);——unset($v)这行不能省 - 漏掉
unset()后,再执行$arr[] = 4;,新元素值可能被上一轮$v覆盖(具体表现取决于 PHP 版本和 zval 状态) - PHP 7.0.0+ 在循环结束后自动断开引用,但仅限于非引用赋值场景;若循环体中有
$v = &some_other_var;,仍需手动unset - 更安全的做法:改用
for或array_walk,避免引用变量逃逸
global和static变量天然支持引用,但语义不同
global $x;本质就是创建当前作用域变量到全局变量的引用,而static $y;在函数内维持的是单例存储,多次调用共享同一内存位置——两者都无需&就能跨作用域读写,但机制完全不同。
容易混淆的是:把static变量当“全局缓存”用时,误以为它像global一样可被任意地方修改,其实它只在定义它的函数内可写(除非你把它作为引用返回出去)。
-
function f() { static $s = 0; return ++$s; }—— 每次调用返回递增值,$s 自动保持引用关系 -
function &g() { static $s = []; return $s; }—— 返回引用,外部可直接修改$s -
global $g; $g = [];和function f() { global $g; $g[] = 1; }—— 等价于$g在各处都是同一份 - 注意:
static变量初始化表达式只执行一次,且不能是复杂表达式(如static $x = get_val();在 PHP 8.1+ 才允许)
引用不是语法糖,是内存层面的共享。只要有一个地方修改了值,所有引用它的地方都会变——这个事实本身简单,但嵌套在函数、循环、静态变量里时,谁在什么时候绑定了谁,很容易想岔。