PHP 7.4+ 中无法用展开运算符(...)合并含字符串键的关联数组,因其仅支持连续数字索引数组;应使用 array_merge()、+ 操作符或 PHP 8.1+ 的 array_merge_recursive()。

这是 PHP 7.4+ 使用展开运算符(...)合并关联数组时的常见报错。根本原因是:PHP 不允许对含字符串键的数组直接使用 ... 展开,它只支持索引数组(数字键且从 0 开始连续)。
为什么会出现这个错误
当你写类似这样的代码时:
$a = ['name' => 'Alice']; $b = ['age' => 30]; $result = [...$a, ...$b]; // ❌ 报错:Cannot unpack array with string keys
PHP 解析器在遇到 ... 时,会尝试把数组当作可遍历的“列表”来展开,但字符串键破坏了这种线性结构预期,所以直接拒绝。
正确合并关联数组的几种方法
✅ 推荐:用 array_merge()
最常用、语义清晰、专为关联数组设计:
-
array_merge($a, $b)会合并键值,相同字符串键时,后一个数组的值覆盖前一个 - 支持任意数量数组:
array_merge($a, $b, $c, $d) - 注意:会重置数字键(变成 0,1,2…),如果需保留数字键,用
+合并(见下条)
✅ 保留数字键?用数组联合操作符 +$a + $b 表示“以 $a 为基准,仅把 $b 中 $a 不存在的键补上”:
- 键冲突时,左边数组的值优先(不覆盖)
- 数字键也被视为“键”,所以
[0 => 'x'] + [0 => 'y']结果仍是[0 => 'x'] - 不能链式写多个:
$a + $b + $c是合法的,但逻辑是($a + $b) + $c
✅ PHP 8.1+:用 array_merge_recursive() 或自定义逻辑
如果需要深度合并(比如嵌套数组),或想避免覆盖、改为合并同名值(如转成数组),可用:
-
array_merge_recursive():遇到相同键时,把值装进数组,而不是覆盖 - 自己写递归合并函数,或使用 Laravel 的
Arr::mergeRecursive()等工具类
哪些情况看似能用 ... 实际仍会报错
这些写法都 ❌ 不行:
-
[...array_values($a), ...array_values($b)]—— 虽然转成了数字键,但结果丢失原始键名,不是真正“合并关联数组” -
[...$a, ...$b]即使 $a 和 $b 都是空数组或只有数字键,只要其中任一含字符串键就失败 - 试图用
foreach+...拆包单个元素 —— 展开运算符只能用于函数参数或数组字面量中,不能用于循环体内赋值
一句话总结
要合并关联数组,别碰 ...;用 array_merge() 处理一般覆盖场景,用 + 保留左侧优先级,用 array_merge_recursive() 处理嵌套需求。展开运算符只适合纯索引数组或函数调用传参。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











