php数组默认值传递(写时复制),修改时才复制;引用传递需用&符号,直接操作原数组;赋值默认不共享,$b =& $a才共享;php 7+优化引用跟踪但func_get_args()等场景仍存副本。

PHP 中数组的传递方式直接影响函数内部对数组的修改是否会影响原始数组。值传递时,函数操作的是副本;引用传递时,操作直接作用于原数组。关键区别在于是否使用 & 符号声明参数为引用,以及 PHP 7+ 对数组“写时复制”机制带来的行为变化。
值传递:默认行为,安全但可能低效
函数参数不加 & 时,PHP 默认按值传递数组。但注意:这并非真正“复制整个数组”,而是采用 写时复制(Copy-on-Write) 机制——仅当函数内修改数组内容时,PHP 才实际复制一份副本。
- 未修改数组时:内存共享,无额外开销
- 修改数组元素或结构(如 unset()、[]=)时:触发复制,原始数组不受影响
- 适合读取操作或需保持原数组不变的场景
引用传递:显式声明,修改直接影响原数组
在函数定义和调用时均使用 &(如 function foo(&$arr)),则数组以引用方式传递。此时函数内所有操作都直接作用于原始数组内存地址。
- 增删改查均同步反映到原变量
- 避免大数组复制开销,适合需原地修改的场景(如批量处理、递归构建)
- 需注意副作用:调用方需明确知晓并接受原数组被改变
易混淆点:赋值操作中的引用与普通变量不同
数组赋值($b = $a;)默认仍是值传递语义(受写时复制保护),不同于对象默认引用语义。若想让两个变量指向同一数组,必须显式使用 &:
立即学习“PHP免费学习笔记(深入)”;
- $b = $a; → 独立副本(后续修改互不影响)
- $b =& $a; → 共享同一数组(任一变量修改,另一变量立即可见)
- 该规则同样适用于函数返回值、foreach 循环变量等上下文
PHP 7+ 的优化与兼容性提醒
PHP 7 引入更严格的引用跟踪机制,使写时复制更精准,减少了意外复制。但以下情况仍需警惕:
- 函数内使用 func_get_args() 获取参数时,即使原参数是引用,获取到的也是副本
- 可变函数调用(call_user_func())中,引用传递需显式传入 &$var,否则失效
- 扩展开发或深度调试时,可通过 xdebug_debug_zval() 查看变量的引用计数与是否为引用







