同名键合并是否覆盖取决于键类型:字符串键被后者覆盖,数字键重排追加;+运算符左优先不覆盖;array_merge_recursive()对字符串键自动合并为数组,数字键仍追加。

同名键合并后是否覆盖,取决于键的类型:字符串键会覆盖,数字键会重排追加。
字符串键(关联数组)总是被后面值覆盖
只要键名是字符串(比如 "name"、"id"),array_merge() 遇到重复键时,直接用后一个数组的值替换前一个——不保留、不报错、不合并。
- 常见错误现象:
array_merge(['a' => 1], ['a' => 2])返回['a' => 2],不是['a' => [1, 2]],也不是报错 - 使用场景:配置覆盖(如默认配置 + 用户配置),你明确希望“后者优先”
- 容易踩的坑:误以为会自动合并成数组,结果关键字段静默丢失;尤其在读取多个 API 响应后拼装数据时
数字键(索引数组)不会覆盖,但会重排索引
键名是纯整数(如 0、1、5)时,array_merge() 不做覆盖,而是把所有值顺序拼接,再从 0 开始重新编号。
- 常见错误现象:
array_merge([1 => 'x'], [1 => 'y'])返回[0 => 'x', 1 => 'y'],原键1全部消失 - 使用场景:合并多个查询结果列表(如分页拉取的用户数据),需要扁平化处理
- 性能影响:重排本身开销小,但若后续逻辑依赖原始键(比如用
$items[1]取第二条),就会出错
想保留原键?别用 array_merge(),改用 + 运算符
+ 对所有键类型都“左优先”:左边数组的键存在,右边同名键就直接跳过,不覆盖也不重排。
立即学习“PHP免费学习笔记(深入)”;
- 示例:
['a' => 1, 0 => 'x'] + ['a' => 2, 0 => 'y']→['a' => 1, 0 => 'x'] - 适用场景:补全默认值(如
$config + $defaults),或合并结构松散、需保留原始位置的数组 - 注意点:
+不递归,不处理多维;遇到null或未定义键也不会触发警告,但也不会帮你修复数据结构
要真正合并同名键下的数组值?用 array_merge_recursive()
它对字符串键的重复值不做覆盖,而是自动包成数组;数字键仍按顺序追加。
- 示例:
array_merge_recursive(['a' => 1], ['a' => 2])→['a' => [1, 2]] - 陷阱:如果某个同名键的值不是数组(比如一个是
1,一个是['x']),它会把非数组值转成数组再合并,结果可能不符合预期 - 复杂点在于:它无法控制“覆盖 vs 合并”的粒度——要么全递归,要么不用;业务上常需手写逻辑来判断何时覆盖、何时追加



















