PHP 5.6+ 的...运算符用于函数定义中声明剩余参数,必须位于参数列表末尾且仅出现一次,自动打包多余实参为数组;调用时可展开数组传参,支持类型提示,但不支持默认值和引用。

PHP中...运算符的基本用法
PHP 5.6+ 支持用...(俗称“展开运算符”或“变长参数语法”)在函数定义中接收不确定数量的参数,它会把多余实参自动打包成一个数组,比老式的func_get_args()更直观、类型更安全。
关键点:它不是“可选参数”,而是“剩余参数”的声明方式,必须放在参数列表末尾,且只能出现一次。
-
function sum(...$numbers) { return array_sum($numbers); }—— 正确,$numbers是array -
function bad($a, ...$rest, $b) { }—— 错误,...不能在中间或末尾有其他必填参数 -
function also_bad(...$a, ...$b) { }—— 错误,只允许一个...
与func_get_args()对比时要注意什么
老代码常用func_get_args()手动取参,但它的返回值是普通数组,不参与函数签名,IDE无法推断、PHPStan/ Psalm 难以静态分析,且调用时无法强制类型约束。
而...声明的参数可以加类型提示,也能被反射识别:
立即学习“PHP免费学习笔记(深入)”;
function logMessages(string $prefix, ...$messages): void {
foreach ($messages as $msg) {
echo "$prefix: $msg\n";
}
}
- 调用
logMessages('INFO', 'user logged in', 123, true)合法,$messages为['user logged in', 123, true] - 若写成
function logMessages(string $prefix, ...array $messages),则123和true会触发TypeError -
func_get_args()对类型完全无感知,错误只能运行时暴露
调用时用...展开数组传参
同一个...符号,在函数调用处还能反向“展开”数组,把数组元素当多个独立实参传入 —— 这和定义时的语义不同,但共用同一语法。
-
array_merge(...$arrays)等价于把$arrays里每个子数组作为单独参数传给array_merge -
call_user_func_array('foo', $args)可直接写成foo(...$args),更简洁、无函数调用开销 - 注意:被展开的变量必须是数组或Traversable,否则报
Fatal error: Uncaught TypeError - 空数组
...展开后相当于没传任何额外参数,不会报错
常见坑:类型声明 + 引用 + 默认值组合失效
...参数不支持默认值,也不能加引用(&),加了会直接解析失败:
-
function bad(...$items = []) { }→ 语法错误:SyntaxError: Default value for parameters with the ... operator are not allowed -
function also_bad(...&$items) { }→ 语法错误:Parse error: syntax error, unexpected '&', expecting variable (T_VARIABLE) - 想实现“可选数组参数”,应改为显式接受一个数组参数:
function good(array $items = []) { },而非硬套... - 混合使用时,必填参数仍需满足顺序和数量,
...只收尾部多余参数
最易忽略的是:哪怕你只传一个参数,...声明的变量仍是数组(长度为1),别下意识当成标量处理。



















