PHP中两个变量指向同一块内存需用引用赋值$a=&$b,而非$a=$b;对象因存储句柄而天然共享,数组则需显式加&才引用;可用debug_zval_dump()检查引用关系。

PHP中让两个变量指向同一块内存(引用赋值)
PHP默认是值传递,赋值时会复制一份数据。如果想让两个变量共享同一个值——改一个另一个也变,必须用引用赋值,而不是普通等号 =。
常见错误是以为 $a = $b 就能联动修改,实际只是拷贝当前值。真正生效的是加 & 的写法:$a = &$b。
-
&必须写在赋值号右边的变量前,即$a = &$b,不是$a =& $b(虽然后者在老版本兼容,但语义模糊,不推荐) - 引用关系一旦建立,后续对任一变量的赋值(包括
unset())都可能影响另一方:比如unset($b)不会断开引用,但$b = null会让$a也变成null - 函数参数传引用、
foreach中用&$v修改数组元素,底层逻辑和这个一致
数组或对象变量天然“共享”的错觉从哪来
对象和数组在 PHP 7+ 中默认使用“写时复制”(copy-on-write)机制,看起来像共享,其实不是真正的引用。
例如:$a = ['x' => 1]; $b = $a; $b['x'] = 99; —— 此时 $a 不变。只有当你显式用 $b = &$a,改 $b 才会影响 $a。
立即学习“PHP免费学习笔记(深入)”;
- 对象变量存储的是对象标识符(handle),多个变量指向同一个对象实例,所以
$obj1->prop = 1会影响$obj2->prop(前提是$obj2 = $obj1) - 但若执行
$obj2 = clone $obj1,就彻底分离了 - 数组没有这种行为,纯数组赋值永远是深拷贝(值复制),除非你主动加
&
检查两个变量是否真的引用同一内存
不能靠 === 或 == 判断,它们比的是值或类型。PHP 提供了 xdebug_debug_zval()(需启用 Xdebug)或更轻量的 debug_zval_dump() 查看引用计数(refcount)和是否为引用(is_ref)。
- 如果
is_ref是1且refcount > 1,基本可确认是引用关系 - 注意:
debug_zval_dump()在 CLI 模式下更准,Web 环境可能因输出缓冲干扰结果 - 简单验证可用:
$a = 1; $b = &$a; $a = 2; var_dump($b); // 输出 int(2)
引用赋值的典型误用场景
最容易翻车的地方是循环中误用引用,导致变量残留引用关系,影响后续逻辑。
- 常见坑:
foreach ($arr as &$item) { ... }结束后没unset($item),下次循环或同作用域其他代码再用$item,可能意外修改原数组最后一个元素 - 函数返回引用时,必须在函数定义和调用处都加
&:function &getRef() { return $var; }+$x = &getRef(); - 超全局变量(如
$_POST)不能被引用赋值,$post = &$_POST会报Notice: Indirect modification of overloaded element
& 是不是只出现在该出现的地方。



















