php函数默认按值传递,修改不影响原变量;要修改外部变量,必须在函数定义和调用时都加&,缺一不可。

PHP函数里改不了变量值?检查是不是忘了加&
PHP默认按值传递参数,函数内部改的是副本,原变量不受影响。想让函数修改外部变量,必须在定义和调用时都显式加&——缺一不可。
常见错误现象:function swap($a, $b) { $tmp = $a; $a = $b; $b = $tmp; } 调用后$x和$y完全没变;或者只在函数定义写&$a,调用时漏了&,PHP 8.0+会直接报Deprecated: Call-time pass-by-reference警告。
- 定义函数时:参数前加
&,如function modify(&$data) - 调用时:实参前也要加
&,如modify(&$user['name'])或modify(&$config) - 不能对表达式、字面量或临时结果取引用,比如
modify(&getArray()[0])或modify(&'hello')会报Cannot pass parameter by reference
数组元素能单独传引用吗?可以,但要注意语法细节
给数组某个键传引用是高频需求,比如批量处理配置项、递归修改嵌套结构。但$arr['key']本身不是变量,而是表达式,直接加&会失败。
正确做法是先用变量承接该元素,再传引用:
立即学习“PHP免费学习笔记(深入)”;
$item = &$config['database']['host']; updateConfig($item); // $config['database']['host'] 现在已被修改
- 不能写
updateConfig(&$config['cache']['ttl'])——PHP解析器不认这种“动态左值” - 如果要循环修改多个数组元素,用
foreach ($arr as &$v),但记得结束后unset($v),否则$v仍指向最后一个元素,下次循环可能意外覆盖 - 对
$_POST或$_GET这类超全局数组的元素,同样适用该规则,但不建议直接改它们,容易引发逻辑混乱
对象为什么不用&也能“像引用一样”工作?
PHP 5.0+起,对象变量存储的是对象标识符(类似指针),赋值或传参时复制的是这个标识符,不是对象本身。所以function process($obj) { $obj->prop = 'new'; }确实能改原始对象属性——但这不是引用传递,是对象模型的天然行为。
- 对对象用
&$obj反而多余,除非你真想让函数替换整个对象实例(比如$obj = new Logger();) - 资源类型(如
fopen()返回的resource)行为类似对象,也不需要& - 字符串、数组、整数等标量类型,没有这种“自动共享”,必须靠
&才能穿透作用域
引用传参会影响性能或产生副作用吗?
引用本身开销极小,但容易掩盖数据流向,尤其在深层调用链中。真正的问题不在性能,而在可维护性。
- 被引用的变量生命周期会被延长——只要还有引用存在,它就不会被GC回收,大数组或大对象长期驻留内存
- 函数签名不带
&时,调用者默认认为“安全无副作用”;一旦加了&,就必须检查所有调用点是否预期被修改 - PHP 7.4+支持箭头函数,但箭头函数不能使用引用参数,
fn(&$x) => $x++是语法错误
复杂点在于:引用不是“开关”,而是一条隐式连接线。你得同时盯住函数定义、每次调用、以及被传入的变量是否还在其他地方被读写——稍不注意,就变成“谁动了我的变量”。











