array_merge() 拼接数组并重排数字键、后值覆盖同名字符串键;+ 运算符左侧优先联合、不覆盖已有键;array_replace() 顶层按键覆写、数字键也覆盖;三者均不递归,嵌套需 array_replace_recursive() 或手动处理。

array_merge() 是拼接,不是替换
它把所有数组“摊平”后按顺序连起来,数字键一律重排(从 0 开始),字符串键冲突时后值覆盖前值。你不能把它当成“用 $b 补全 $a 的缺失字段”来用——它不保留 $a 的原始结构。
常见错误现象:array_merge() 合并两个带隐式数字键的数组后,原键 0、1 消失,变成 0、1、2、3;若 $a 和 $b 都有 'host' 键,$b 的值会直接顶掉 $a 的,没得商量。
- 只适合纯索引数组追加,比如日志条目合并、列表拼接
- 传入
null或非数组会触发Warning: array_merge(): Expected parameter X to be an array - 多个参数合法:
array_merge($a, $b, $c)等价于逐层合并
+ 运算符是联合,不是合并
+ 不是加法,是“左侧优先取键”的联合操作:相同字符串键,右侧被丢弃;相同数字键,右侧也被丢弃(不是覆盖,是跳过);只补充左侧没有的键。
典型误用场景:想用 $config + $defaults 填默认值,结果发现 $config 里缺的键补上了,但 $config 自己的数字索引(比如 [0 => 'admin'])和 $defaults 的同位置数字键([0 => 'guest'])根本不会发生任何交互——0 已存在,'guest' 直接消失。
- 适合构建“基础配置 + 可选覆盖”的扁平结构,如路由定义、HTTP header 数组
- 允许右侧为
null:$arr + null等价于$arr,不会报错 - 不支持三元写法语义:
$a + $b + $c实际是($a + $b) + $c,仍只保最左
array_replace() 才是真替换
array_replace() 明确以第一个数组为模板,后续数组仅用来“按键覆写”:字符串键冲突时右侧覆盖左侧,数字键冲突时也覆盖(不重排!),且只作用于顶层。
容易踩的坑:它不会递归进子数组。比如 $base = ['db' => ['host' => 'localhost']] 和 $override = ['db' => ['port' => 5432]],array_replace($base, $override) 结果是 ['db' => ['port' => 5432]] ——整个 'db' 子数组被替换了,原 'host' 彻底丢失。
- 适合“配置覆盖”类场景,比如环境变量注入、CLI 参数合并
- 数字键行为和字符串键一致:右侧值直接落位,键名不动
- 若需递归覆盖,请换用
array_replace_recursive(),但注意它对非数组值的处理很特殊(会自动包裹成数组)
嵌套结构必须递归处理
只要数组里有子数组,array_merge()、+、array_replace() 全部失效——它们都只看第一层键。想合并 'options' 里的 'timeout' 和 'charset',必须用 array_replace_recursive() 或手动遍历。
但 array_replace_recursive() 也有陷阱:当某键在 $a 中是字符串,在 $b 中是数组,它不会报错,而是把字符串转成数组再合并(例如 'timeout' => 5 变成 ['timeout' => 5]),最终结构可能和预期不符。
- 深度合并没有银弹,复杂场景建议封装函数,显式控制每层逻辑
- PHP 8.5.5 仍未改变这些函数的行为,兼容性无需额外顾虑
- 最易忽略的一点:所有这些函数都不修改原数组,返回新数组——别忘了赋值
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











