PHP中&不是万能胶,本质是共享内存而非传地址;函数参数引用只接受真实变量,foreach后需unset避免串味,return &需调用端同步加&,盲目引用反而降低性能。

PHP里的&不是万能胶,乱加容易粘住自己。它本质是让两个变量共享同一块内存,而不是简单“传地址”或“提速”。用错地方,轻则逻辑错乱,重则跨版本报错、调试困难、性能反降。
函数参数加&只认变量,不接受任何“计算结果”
函数声明里写function foo(&$x),调用时必须传一个**真实存在的变量**:
-
✅ 可以:
$v = 123; foo($v); -
❌ 报错:
foo(42)、foo($arr[0])、foo(get_data())、foo($obj->prop)(PHP 7.4+ 对对象属性引用更严格)
错误提示通常是 Cannot pass parameter 1 by reference——不是语法错,是运行前就拒绝执行。
foreach中用&后不unset,下一轮就“串味”
写foreach ($arr as &$item),循环结束后$item仍指向数组最后一个元素。如果后续又定义$item = 'new',原数组末尾值就被悄悄改了。
立即学习“PHP免费学习笔记(深入)”;
- PHP 5 和 7/8 都存在此问题,但 PHP 7+ 的内部优化会让这种“残留引用”行为更隐蔽、更难复现
-
固定动作:循环一结束,立刻
unset($item),彻底切断引用
return & 返回引用,调用端漏写&就白忙活
函数声明为function &get_cfg() { static $c = []; return $c; },意图是返回可修改的静态配置引用。但调用时:
-
❌ 无效:
$cfg = get_cfg();→ 得到副本,改它不影响原始配置 -
✅ 必须:
$cfg = &get_cfg();→ 少一个&,就是普通赋值
这个错误是静默的:不报错、不警告,只在业务逻辑出问题时才暴露,极难定位。
以为加&能省内存?多数时候是白费劲
PHP底层有成熟的“写时复制(Copy-on-Write)”机制。对数组或对象做只读操作,根本不会拷贝;只有真正修改时,Zend引擎才按需分离。
- 盲目给大数组参数加
&,反而可能干扰优化,实测性能下降超30% - 真要避免拷贝,先用
memory_get_usage()和microtime()测,别靠猜 - 更推荐做法:函数返回新数组/对象,语义清晰、线程安全、利于单元测试



















