PHP函数参数默认按值传递,要修改原变量必须在函数定义时用&声明引用参数;调用时加&已被废弃,且引用参数只能传变量,适用场景包括就地更新、多输出变量和避免大数组复制。

PHP函数参数默认按值传递,但要真正修改调用方的变量,必须显式使用引用传递——也就是在函数定义的参数前加 & 符号。这不是可选项,是强制语法要求;漏掉 &,哪怕逻辑意图是“改原变量”,结果也只会作用于副本。
为什么 & 必须写在函数定义里,而不是调用时
PHP 的引用绑定发生在函数声明阶段,不是调用阶段。调用时加 &(比如 myfunc(&$x))在 PHP 5.3+ 已被废弃,7.4 起直接报 Deprecated: Call-time pass-by-reference 错误。
- 正确写法:函数定义时声明
function update(&$val) { $val .= '!'; } - 错误写法:定义为
function update($val),调用却写update(&$x) - 调用时传入的必须是变量,不能是字面量或表达式,例如
update($a)合法,update(123)或update($a + 1)会触发Fatal error: Only variables can be passed by reference
& 引用传递的实际适用场景
不是所有“想改外面变量”的地方都适合用引用。它真正必要的场景是:函数职责明确包含“就地更新”且调用方依赖该副作用。
- 批量修改数组元素,比如
function normalizeKeys(&$arr)直接重键名 - 解析配置并填充多个输出变量,如
parseIni($file, &$sections, &$errors) - 避免大数组复制开销(尤其 PHP 7.0 前,ZVAL 复制成本高)
- 注意:对象本身在 PHP 5+ 中默认就是“句柄传递”,
$obj参数即使不加&,也能在函数内修改其属性;只有当你需要替换整个对象引用(比如$obj = new OtherClass())才需&$obj
容易踩的坑:默认参数 + 引用混用
PHP 允许给引用参数设默认值,但有严格限制:默认值只能是 null 或常量表达式,不能是变量、函数调用或数组字面量。
立即学习“PHP免费学习笔记(深入)”;
- 合法:
function logError(&$msg = null, $level = 'warning') - 非法:
function bad(&$data = getData())→Parse error: default argument is invalid - 更隐蔽的坑:如果函数同时有默认参数和引用参数,引用参数不能放在默认参数之后,否则调用时位置歧义。例如
function foo($a, &$b = null)是错的;必须写成function foo(&$b = null, $a)或全部非默认参数在前
引用传递看着简单,但它的影响是全局的——一旦函数内部意外改了 $var,所有持有该变量的地方都会感知到。与其依赖引用“悄悄改”,不如多数时候返回新值、让调用方决定是否赋值,这样逻辑更透明、测试更容易。



















