php中函数引用传递必须且只能在定义时形参前加&,调用时不加;数组元素需先赋值变量再传引用;foreach引用遍历后须unset避免意外覆盖;对象/资源默认可修改内容,&仅用于替换实例,且引用会延长内存生命周期。

函数定义时加 & 是唯一合法方式
PHP 5.1.0 起,调用时写 &$var 会触发 Deprecated: Call-time pass-by-reference 警告;PHP 8.0+ 直接报致命错误。必须且只能在函数声明的形参前加 &,例如:function updateConfig(&$config)。调用时写 updateConfig($config) 即可——& 不出现在调用侧。
常见错误现象:function swap(&$a, &$b) { ... } 定义正确,但调用写成 swap(&$x, &$y) 就挂了;或者只在定义漏掉一个 &,结果只有部分参数被引用,逻辑错乱却无报错。
数组元素不能直接传引用,得先落地为变量
$arr['key'] 是表达式,不是左值,modify(&$arr['host']) 会报 Cannot pass parameter by reference。必须拆成两步:
- 先用普通变量承接:
$host = &$config['database']['host']; - 再把该变量传入:
updateHost($host);
对嵌套结构(如 $config['cache']['ttl'])也一样。别试图用 $$ 或 eval 绕过——语法不支持,且极度危险。
foreach 引用遍历后必须 unset($v)
写 foreach ($data as &$item) 确实能原地修改数组元素,但循环结束后,$item 仍持有对最后一个元素的引用。下次再用 $item = 'xxx',会意外覆盖原数组末尾项。
安全做法是循环完立刻 unset($item)。如果后续还要读写这个变量,就重命名它(比如叫 $ref),避免和常规变量名冲突。
对象和资源不用 & 也能“改内容”,但 & 有特殊用途
对象变量存的是标识符(类似指针),所以 function process($obj) { $obj->name = 'new'; } 本来就能改原始对象属性——这不是引用传递,是对象模型特性。加 &$obj 只在一种场景有用:你想让函数彻底替换整个对象实例,比如 $obj = new Logger();。否则纯属冗余,还可能误导协作者。
同理,fopen() 返回的 resource 也不需要 & 来维持状态变更。
真正容易被忽略的是引用延长生命周期这件事:只要还有变量引用着某个大数组,它就不会被 GC 回收。在长生命周期脚本(如 CLI 任务、Swoole Worker)里,忘了清理引用,内存就悄悄涨上去了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











