展开运算符[...$arr]仅在表达式中合法且要求操作数全为数组,array_merge(...$arr)更安全高效;合并多维数组时前者易崩溃,后者可跳过非数组项并优化性能。

PHP 7.4+ 中用 [...$arr] 合并数组确实更简洁,但「优雅」不等于无条件套用——它只在特定上下文安全高效,盲目替换 array_merge() 反而引入兼容性、语义或性能风险。
展开运算符只在表达式上下文中合法
你不能把它用在赋值左侧、类属性默认值、const 定义或函数参数接收端(那是 ... 收集语法)。常见误用:
-
$arr = [...$a, ...$b];✅ 合法:字面量数组构造 -
public $data = [...$a];❌ 解析失败:静态上下文不支持展开 -
function foo(...$args) { ... }✅ 这是参数收集,不是展开
错误现象通常是 Parse error: syntax error, unexpected '...',本质是语法阶段被拒绝,和运行时无关。
合并多维数组时,array_merge(...$arr) 比 [...$arr] 更可靠
当你要把一个二维数组(如 $arr = [[1,2], [3,4], [5]])扁平成一维,两种写法行为不同:
-
array_merge(...$arr)→[1,2,3,4,5],且 PHP 7.4+ 对此做了底层优化,实测比循环快 3–5 倍 -
[...$arr]→ 直接报Warning: array_merge(): Argument #1 is not an array(如果$arr为空)或Fatal error(如果含非数组项)
关键差异:array_merge() 会跳过非数组元素(仅 warning),而展开运算符要求每个操作数都必须是数组或可遍历对象,否则直接 fatal。
保留字符串键时,别用 array_merge 或展开
如果你的子数组带关联键(如 ['id' => 1, 'name' => 'A']),array_merge(...$arr) 和 [...$arr] 都会覆盖重复键,且重置数值索引。此时应改用:
$result = [];
foreach ($arr as $sub) {
if (is_array($sub)) {
$result += $sub;
}
}
+= 不重置键、不覆盖已有键(只追加新键),中等规模下还比 array_merge 快 20% 以上。但注意:它不递归,只展平一层。
空数组或脏输入会让展开语法瞬间崩溃
array_merge(...[]) 在 PHP 7.4+ 报 Warning: array_merge() expects at least 1 parameter, 0 given,还能继续执行;而 [...[]] 虽然语法合法,但若 $arr 里混了 null 或字符串,[...$arr] 就直接 Fatal error: Uncaught TypeError。
真实项目里,输入来源不可控——数据库字段可能为 NULL、API 返回结构可能变异。这时候硬上展开语法,等于把类型校验甩给 PHP 解析器,而不是自己处理。
复杂点往往不在“怎么写”,而在“谁来保证输入干净”。展开运算符省了几个字符,却把防御成本推到了调用链上游,这点容易被忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











