
PHP 中引用传递和值传递的核心区别在于:值传递是复制变量内容,修改不影响原变量;引用传递是让两个变量指向同一内存地址,修改会相互影响。
值传递(默认行为)
函数参数默认按值传递。PHP 会创建原变量的一个副本,函数内对参数的修改不会影响外部变量。
例如:
$a = 10;
function increment($x) {
$x++;
echo $x; // 输出 11
}
increment($a);
echo $a; // 仍为 10
注意:对于数组、对象等复合类型,PHP 7+ 使用“写时复制(Copy-on-Write)”机制——只要不修改,就不真正复制内存;一旦赋值或修改,才分离副本。这提升了性能,但语义上仍是值传递。
立即学习“PHP免费学习笔记(深入)”;
引用传递(需显式声明)
在参数前加 & 符号,使形参成为实参的别名,二者共享同一内存空间。
例如:
$a = 10;
function incrementByRef(&$x) {
$x++;
}
incrementByRef($a);
echo $a; // 输出 11
- 必须在函数定义和调用时都体现引用(定义带 &,调用时无需额外符号)
- 不能对字面量或表达式传引用(如 func(&$a + 1) 会报错)
- 返回引用也需用 &functionName() 定义,并用 & 接收(如 $b = &getValue();)
对象的特殊性(常被误解)
PHP 5 及以后,对象变量本身存储的是对象标识符(类似句柄),而非实际数据。因此:
- 对象作为参数传入时,虽是值传递,但传递的是标识符的副本——两个变量指向同一个对象实例
- 修改对象属性会影响原对象(因为操作的是同一对象),但重新赋值($x = new StdClass();)不会改变原变量
所以“对象默认按引用传递”是常见误区;准确说是“按标识符值传递”,效果类似引用,但机制不同。
如何选择?
优先使用值传递,符合函数式习惯、线程安全、逻辑清晰。
仅在以下情况考虑引用传递:
- 需要函数直接修改外部变量(如解析多返回值、批量更新数组)
- 处理超大数组或字符串,避免复制开销(但应先分析是否真成瓶颈)
- 实现类似 PHP 内部函数 sort()、mysqli_stmt_bind_param() 的原地操作接口
滥用引用可能引发隐式耦合、调试困难、难以测试等问题,面试中强调“明确意图”比“追求性能”更重要。










