array_merge()覆盖字符串键、重排数字键;+保留左右键不覆盖;array_merge_recursive()递归合并同名键;array_replace()按键替换不重索引。

array_merge() 会覆盖字符串键,但重排数字键
如果你用 array_merge() 合并两个关联数组,相同字符串键的值会被后一个数组覆盖,而数字键(哪怕隐式生成的)会被重新索引,不再保留原始位置。
- 适合场景:你明确希望“右侧优先”,且不关心数字索引顺序(比如合并配置项、表单字段默认值 + 用户输入)
- 常见错误:误以为
array_merge(['id' => 1], [0 => 'a'])会保留0键 → 实际结果中0变成新数组的索引0,但若左侧也有数字键,它会被挤到后面 - 示例:
$a = ['name' => 'Alice', 0 => 'x']; $b = ['name' => 'Bob', 0 => 'y']; array_merge($a, $b)返回['name' => 'Bob', 0 => 'x', 1 => 'y']
+ 运算符保留左侧字符串键,也保留左侧数字键
+ 不是加法,是「数组联合」:它把右侧数组中「左侧没有的键」追加进去,已有键一律忽略右侧值。这个行为对关联数组特别友好,但容易被当成“简单拼接”误用。
- 适合场景:合并配置数组、路由定义、多层默认设置(你想让基础配置不被覆盖)
- 关键细节:它对数字键也按“是否存在”判断,不是按值合并 ——
[0=>'a'] + [0=>'b']结果仍是[0=>'a'],0被视为已存在 - 陷阱:如果右侧数组有更长的数字索引序列(如
[2=>'c', 3=>'d']),而左侧只有[0=>'a'],那2和3会被完整保留,不会和0拼成连续索引
array_merge_recursive() 把同名字符串键转成数组
当你要保留所有同名键的值,而不是覆盖或丢弃,array_merge_recursive() 是唯一选择。它对字符串键做递归合并,对数字键仍按追加处理。
- 适合场景:合并用户提交的嵌套表单数据、多语言字段、权限规则树
- 注意点:一旦触发递归(比如两个数组都有
'tags'键),结果里'tags'就变成数组了,后续代码必须适配这种结构 - 示例:
$a = ['tags' => ['php']]; $b = ['tags' => ['mysql']]; array_merge_recursive($a, $b)得到['tags' => ['php', 'mysql']];但如果$a['tags']是关联子数组(如['name'=>'php']),那结果就是['tags' => [['name'=>'php'], ['name'=>'mysql']]
别漏掉 array_replace():按键替换,不重索引数字键
array_replace() 常被忽略,但它在关联数组合并中非常精准:只替换同名键的值,数字键不重排、不合并、不递归,完全按键名一对一覆盖。
立即学习“PHP免费学习笔记(深入)”;
- 适合场景:补全/修正一个已有数组的特定字段(如从数据库读出用户数据后,用 API 返回的更新字段覆盖部分值)
- 和
array_merge()的核心区别:array_merge([0=>'a', 'x'=>1], [0=>'b', 'x'=>2])→[0=>'b', 1=>'a', 'x'=>2];而array_replace()→[0=>'b', 'x'=>2],原0键被替换,不新增索引 - 兼容性:PHP 5.3+,比展开运算符(PHP 7.4+)覆盖范围更广



















