PHP函数默认值传递,但array/object在PHP 7+为写时复制;真正引用传递需显式加&;对象属性修改不需&因存句柄;&仅用于修改变量本身或避免大变量拷贝。

PHP函数传参是值传递还是引用传递?
默认是值传递,但有例外——array、object 类型在 PHP 7+ 实际上是“写时复制”,表面像值传,行为接近引用;而 resource 和 string 纯值传。真正强制引用传递必须显式加 & 符号。
- 不加
&:函数内改$arr不影响外部$arr(除非修改的是数组元素,且该数组未被其他变量引用) - 加
&$arr:函数内unset($arr)或$arr = []会真实清空外部变量 - 对象不用加
&也能“改属性”,是因为对象变量存的是句柄,不是数据本身;但$obj = new StdClass()这种赋值仍是值传递句柄
什么时候必须用 & 引用传参?
只有两类场景真需要:function 要修改原始变量本身(不只是内容),或避免大数组/字符串的内存拷贝(PHP 7.4+ 后者已优化,基本不用操心)。
- 常见误用:给
sort()传&$arr——其实sort()本身就是引用参数,文档写明了sort(array &$array),你再加&会报Strict Standards警告 - 正确用法:自定义函数需重置外部变量,比如
function reset_counter(&$counter) { $counter = 0; } - 危险操作:对超全局数组如
$_POST做&$_POST传参,可能意外破坏请求数据,且部分 SAPI(如 CLI)下行为不一致
可变参数和参数解包怎么不出错?
func_get_args() 和 ...(展开运算符)行为不同:前者返回副本,后者直接转发引用(如果原参数是引用)。
- 用
...$args调用另一个函数时,若$args[0]是引用,目标函数收到的也是引用;但func_get_args()拿到的永远是值 -
call_user_func_array('foo', $arr)不保留引用,哪怕$arr里存的是&$x,进foo的仍是副本 - PHP 8.1+ 支持
mixed参数类型声明,但无法约束是否为引用,运行时仍靠调用方决定
默认参数和类型声明对传参有什么隐性影响?
默认参数值在函数定义时求值,不是调用时;类型声明(如 string $s)会触发自动类型转换或抛出 TypeError,但不影响传递机制本身。
立即学习“PHP免费学习笔记(深入)”;
-
function log($msg = date('Y-m-d'))——每次定义函数时就执行一次date(),不是每次调用才执行 - 传
null给非空类型参数(如string $s),PHP 8+ 直接报错,不会静默转成空字符串 - 数组解构传参(
[$a, $b] = $input)本质是赋值,不是函数传参,别和function foo(array $arr)混淆
& 的边界、对象句柄的迷惑性、以及 ... 和 func_get_args() 的差异,三处最容易在重构或调试时翻车。











