array_merge的参数顺序决定合并后元素位置,严格从左到右追加,字符串键保留、数字键重索引,键冲突时后者覆盖前者,优先级由参数顺序固定。

array_merge 的参数顺序决定合并后元素位置
合并后的顺序不是靠额外排序控制的,而是由 array_merge 函数参数传入的先后顺序直接决定。它严格按「从左到右」把每个数组的元素追加进结果数组,不改变内部顺序,也不自动重排。
常见错误现象:以为调换 $a 和 $b 位置不影响最终结构,其实会彻底改变键值出现顺序和覆盖结果。
- 如果第一个数组有
'name' => 'Alice',第二个有'name' => 'Bob',用array_merge($a, $b)得到的是'name' => 'Bob' - 但用
array_merge($b, $a)就变成'name' => 'Alice'—— 覆盖方向反过来了 - 数字索引数组合并时,
[10, 20]+[30, 40]→[10, 20, 30, 40];反过来就是[30, 40, 10, 20]
字符串键 vs 数字键:重索引行为影响“顺序感”
看似只是“合并”,但数字键会被强制重索引,而字符串键保留原样,这会让开发者误以为“顺序乱了”。实际是规则使然,并非函数 bug。
使用场景:你想拼接两个索引数组(比如日志条目、分页数据),又希望保持原始下标可读性 —— 这时不能依赖 array_merge,得手动处理或改用其他方式。
立即学习“PHP免费学习笔记(深入)”;
-
array_merge([3 => 'x', 5 => 'y'], [3 => 'z'])返回[0 => 'x', 1 => 'y', 2 => 'z'](全部重索引) - 但
['a' => 'x', 'b' => 'y'] + ['b' => 'z']返回['a' => 'x', 'b' => 'y'](+ 运算符不重索引,且丢弃后者的重复键) - 若需保留数字键并避免重索引,用
+运算符更可控,但它不合并同键,只取前者
想覆盖旧值?别只看顺序,先确认键类型
很多人遇到“为什么我的配置没被覆盖”的问题,根源常在键名类型判断失误:你以为是字符串键 'timeout',实际是数字 0 导致被重索引后丢失语义。
性能影响小,但逻辑错位后果严重 —— 特别是在读取配置、合并请求参数等场景。
- 检查键是否全为字符串:
array_keys($arr)看返回值是不是全是string - 混合键数组(如
['a'=>1, 2=>'b'])合并后,数字部分仍会被重索引,字符串部分保留,顺序按参数顺序拼接 - PHP 7.4+ 支持空参数调用
array_merge()返回空数组,可用于安全初始化,避免 undefined notice
真正需要自定义顺序时,别硬套 array_merge
如果你的需求本质是「按某种优先级合并」(比如环境配置 > 默认配置 > 用户配置),array_merge 只能帮你做线性叠加,没法做条件插入或位置插槽。
容易被忽略的地方:很多项目用 array_merge($defaults, $user) 想让用户配置优先生效,结果写成 array_merge($user, $defaults),导致默认值反而覆盖了用户设置 —— 键名相同的情况下,后者才生效。
- 优先级明确时,固定参数顺序即可,例如
array_merge($base, $override) - 需要动态优先级(如根据数组内某个字段排序再合并),就得先
usort或uasort,再逐个array_merge - 多维数组合并要覆盖深层键?
array_merge_recursive不是替代品 —— 它把冲突值变数组,不是覆盖,得自己递归处理或用array_replace_recursive



















