PHP 7.4+展开运算符与array_merge行为一致:字符串键后值覆盖前值,数字键统一重索引追加;本质是PHP刻意将展开语义对齐array_merge以降低学习成本和迁移难度。

PHP 中使用展开运算符(...)合并数组和 array_merge() 行为“一样”,本质是因为它们在**处理键为字符串的关联数组时,都采用“后覆盖前”的语义;在处理数字索引数组时,都执行“重新索引并追加”的逻辑**。但这不是巧合,而是 PHP 8.1+ 对展开运算符的语义明确对齐了 array_merge() 的既定行为。
字符串键:后写入的值生效
两者都把关联数组看作“键映射容器”,遇到重复字符串键时,后面出现的值会覆盖前面的值:
-
array_merge(['a' => 1], ['a' => 2])→['a' => 2] -
[...'a' => 1], [...'a' => 2](实际写法为[...['a' => 1], ...['a' => 2]])→ 同样是['a' => 2]
这符合 PHP 数组“最后赋值胜出”的底层模型,不是“合并”,而是“顺序写入 + 键冲突覆盖”。
数字键:自动重索引,不保留原始键
当数组含纯数字键(如 [0 => 'x', 1 => 'y'])时,两者都会丢弃原键、从 0 开始连续编号:
-
array_merge([0=>'a'], [0=>'b'])→[0=>'a', 1=>'b'] -
[...[0=>'a'], ...[0=>'b']]→ 同样是[0=>'a', 1=>'b']
注意:这不是“合并键”,而是将每个展开数组视为一个**值序列**,依次追加后统一重编号。所以 [...[2=>'x']] 展开后仍是 [0=>'x'],原始数字键被忽略。
关键区别其实藏在细节里
表面行为一致,但底层机制不同,导致某些边界情况结果不同:
-
空数组处理:展开运算符要求操作数必须是数组,
[...null]直接报Fatal error;而array_merge(null)会静默转成空数组,不报错。 -
非数组参数:
array_merge('a', 'b')触发警告并返回false;展开运算符只接受数组或可遍历对象,其他类型直接 TypeError。 -
性能与可读性:展开是语法级特性,无函数调用开销;
array_merge()是函数调用,有栈开销——高频场景中展开略快,且写法更紧凑。
为什么设计成一致?
PHP 团队在引入展开运算符时,刻意将其语义锚定到 array_merge() 这一最常用、最被开发者理解的合并逻辑上。避免引入新规则造成混淆,也降低迁移成本。它本质上就是 array_merge() 的语法糖,只是更现代、更直观。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











