
array_merge() 合并后键名重排,数字索引不保留?
PHP 的 array_merge() 遇到数字键时会重新索引,不是简单拼接。比如 [0 => 'a'] 和 [0 => 'b'] 合并后变成 [0 => 'a', 1 => 'b'],而不是你想要的 [0 => 'a', 0 => 'b'](后者实际会被覆盖)。
要保留原数字键顺序、避免重排,用 + 运算符更直接:
$a = [0 => 'x', 1 => 'y']; $b = [0 => 'z', 2 => 'w']; $result = $a + $b; // [0 => 'x', 1 => 'y', 2 => 'w']
-
+是左优先:左边数组的键存在时,右边同键值被忽略 -
array_merge()是右覆盖:右边数组的同键值会覆盖左边(仅对字符串键;数字键永远重排) - 如果必须保留所有数字键且不重排,只能用
array_merge_recursive()或手动foreach推入
合并关联数组时键冲突怎么处理?
两个关联数组都有 'name' 键,array_merge() 默认用右边值覆盖左边,没有提示、不报错,容易静默丢数据。
常见场景是配置合并、API 返回字段补全。这时候得提前判断或换策略:
立即学习“PHP免费学习笔记(深入)”;
- 用
array_replace_recursive()处理嵌套结构,它会递归合并同名键,而不是粗暴覆盖 - 想保留两边值?改用
array_merge_recursive(),但注意它会把同键值转成数组(哪怕原来只是字符串) - 需要自定义逻辑(比如“左边为空才用右边”)?别硬套内置函数,写个简单
foreach更可控
合并空数组或非数组变量导致 Warning?
array_merge() 要求所有参数都是数组,传了 null、false 或字符串进去,直接报 Warning: array_merge(): Expected parameter 1 to be an array。
真实代码里常从 API 或表单取值,变量未必是数组:
- 用
is_array()提前过滤:array_merge([], is_array($a) ? $a : []) - PHP 7.4+ 可用空合并+类型断言:
array_merge([], $a ?? []),但注意$a是0或''也会被当成空 - 更稳妥:封装一层,比如
safe_merge(...$arrays),内部统一转数组再合并
性能差异:大数组合并选 + 还是 array_merge()?
两者时间复杂度都是 O(n),但 + 在底层不做键重排和类型检查,实际更快,尤其在数字索引多、数组大的时候。
不过有硬限制:+ 不递归,不处理嵌套,也不合并同名字符串键——它只是“左侧数组优先的键集合合并”。所以:
- 纯一维、数字键为主、要速度 → 用
+ - 含嵌套、需递归合并、字符串键多 → 用
array_merge_recursive()或array_replace_recursive() - 不确定输入结构又懒得判断?宁可多一次
is_array(),也别让array_merge()在生产环境崩一次
最常被忽略的是:合并前没验证变量类型,线上突然报 Warning 却查不出源头——因为错误被日志截断,或只在特定请求路径触发。











