array_merge遇相同字符串键名会覆盖而非追加,数字键则被重新索引;若需保留所有键值应使用+操作符或array_replace(后者不重排数字键);处理null等非数组参数时PHP 7.4+会报警告,须提前is_array过滤。

array_merge 合并数组时键名冲突怎么处理
array_merge 遇到相同字符串键名会覆盖,不是追加。比如 array_merge(['a' => 1], ['a' => 2]) 结果是 ['a' => 2];而数字键会被重新索引,array_merge([1, 2], [3, 4]) 得到 [1, 2, 3, 4],不是 [1, 2, 3, 4] 看似正常,但要注意索引重排本身可能破坏顺序依赖。
常见错误现象:用 array_merge 合并两个关联数组后发现某些配置项“消失”了,其实是被后一个数组同名键覆盖了。
- 如果想保留所有键值(不覆盖),改用
+数组合并操作符:$a + $b会保留$a的键,仅把$b中$a不存在的键加入 - 如果必须用
array_merge且要避免覆盖,先确保键名唯一,例如用array_map加前缀或用array_values强制转为索引数组再合并 - 注意空数组传入不会报错,
array_merge([])返回空数组,array_merge(null)才会触发警告
array_merge 处理 null 或非数组参数会怎样
PHP 7.4+ 要求所有参数都必须是数组,传 null、string、int 会直接报 Warning: array_merge(): Expected parameter X to be an array。但 PHP 7.3 及更早版本会静默转成空数组(不推荐依赖)。
典型使用场景:从多个来源收集配置,有些来源可能未定义或返回 null,直接 array_merge($cfg1, $cfg2, $cfg3) 很容易崩。
立即学习“PHP免费学习笔记(深入)”;
- 安全写法是先过滤:用
array_filter([$cfg1, $cfg2, $cfg3], 'is_array')再展开调用array_merge(...$filtered) - 或者逐个判断:
is_array($cfg1) ? $cfg1 : [],再传给array_merge - 别用
@array_merge(...)屏蔽警告——掩盖问题,不解决类型不匹配
和 array_replace 区别在哪,什么时候该换用
array_replace 和 array_merge 行为差异集中在字符串键:两者都会覆盖,但 array_replace 不重排数字键,array_merge 会。比如 array_merge([0 => 'x', 1 => 'y'], [0 => 'z']) 得 [0 => 'z', 1 => 'y'];而 array_replace([0 => 'x', 1 => 'y'], [0 => 'z']) 得 [0 => 'z', 1 => 'y'] ——表面一样,但若第二个数组带稀疏索引如 [5 => 'a'],array_merge 仍会把它塞到末尾并重索引为 2,array_replace 则保留 5。
- 需要保持原始数字键位置(如表单字段顺序、多维数组层级映射),选
array_replace - 想把所有数组“摊平”成连续索引列表(如合并多个查询结果集),用
array_merge -
array_replace不接受null参数,这点和array_merge一致,也要提前判空
性能上,大量小数组合并用 array_merge 还是循环 + []
直接调用 array_merge($a, $b, $c, $d) 比循环中反复 $result = array_merge($result, $next) 快得多,因为后者每次都要复制整个中间数组。但如果你有几十个数组,全列在参数里也不现实,这时建议用 array_reduce:
array_reduce($arrays, 'array_merge', [])
比手动循环清晰,也避免重复分配内存。
- PHP 8.1+ 支持展开运算符,
array_merge(...$arrays)是最简洁写法,但注意$arrays不能太大(受 PHP 函数参数数量限制,通常几千没问题) - 如果数组元素极多(百万级),考虑是否真需要一次性合并——有时流式处理或数据库层聚合更合适
- 别在循环内反复调用
array_merge构建大数组,这是典型的 O(n²) 陷阱
array_merge,还有默认以为关联数组合并会“叠加”而不是“覆盖”。这些细节不看文档、只靠试错很容易卡半天。



















