array_merge()用于合并数组,关联数组同键值后覆盖,索引数组键重排为0起递增;需确保参数均为数组,否则报错;+运算符可保留原键不重排但不覆盖;array_merge_recursive()递归合并但非数组同键会打包成新数组;大数组合并注意性能,PHP 7.4+可用展开语法。

PHP数组合并用 array_merge() 最常用
多数情况下,你要把两个或多个索引数组、关联数组拼成一个,直接用 array_merge() 就行。它会按顺序把参数里的数组“叠”起来:后面数组的值覆盖前面同键名的值(对关联数组),索引数组则重排数字键(从 0 开始递增)。
常见错误是传错参数类型——比如传了个 null 或字符串进去,array_merge() 会直接报 Warning: array_merge(): Expected parameter 1 to be an array, string given。必须确保每个参数都是数组,不确定时先用 is_array() 判断或强制转换:(array)$var。
- 合并两个关联数组:
$result = array_merge($a, $b),$b 中同名键会覆盖 $a - 合并索引数组:
$list = array_merge([1,2], [3,4])→[1,2,3,4],键自动重排 - 想保留原始数字键不重排?用
+运算符代替,但注意:它只取第一个数组中不存在的键,不会覆盖也不会重排
关联数组合并时键冲突怎么处理
当两个关联数组有相同字符串键(比如都叫 "name"),array_merge() 默认用后一个数组的值覆盖前一个。这不是 bug,是设计行为。如果你需要合并值而不是覆盖(比如把两个 "tags" 数组合并成去重后的列表),就得手动处理。
- 覆盖式合并(默认):
array_merge(['name'=>'A'], ['name'=>'B'])→['name'=>'B'] - 追加式合并(不覆盖):
$merged = $a + $b,结果是['name'=>'A'],因为+保留左数组所有键,只补右数组里左数组没有的键 - 要合并同键的数组值(如 tags):
$merged['tags'] = array_unique(array_merge($a['tags'] ?? [], $b['tags'] ?? []))
array_merge_recursive() 和普通合并的区别
当你希望遇到相同键名时不覆盖、而是递归地“往下钻一层”合并(比如两个配置数组都有 "db" 键,你想把它们内部的 "host"、"port" 也分别合并),就该用 array_merge_recursive()。
立即学习“PHP免费学习笔记(深入)”;
但它有个坑:遇到相同键且值都是数组时才递归;如果一个是数组、另一个是字符串,它会把两者都塞进一个新数组里,变成 ['key' => ['old_value', 'new_value']],这往往不是你想要的。
- 安全场景:两组结构一致的配置数组,都含
"logging" => ["level"=>"info", "path"=>"/var/log"] - 危险场景:$a['count'] = 5,$b['count'] = 10 → 合并后变成
['count' => [5, 10]],类型变了 - 替代方案:用循环 + 类型判断手动合并,或借助
array_replace_recursive()(PHP 5.3+),它对非数组值是覆盖而非打包
性能与大数组合并的注意事项
如果数组元素动辄上万,array_merge() 会复制全部数据,内存占用翻倍,速度明显变慢。尤其在循环里反复合并(比如逐条读数据库结果再合并),容易触发内存溢出或超时。
- 避免在循环内调用:
foreach ($items as $item) { $all = array_merge($all, [$item]); }→ 改用$all[] = $item累积 - 合并前确认是否真需要新数组:有时直接用
foreach (array_merge($a, $b) as $v)是临时遍历,可改写为两个 foreach 分别处理,省掉中间数组 - PHP 7.4+ 可用展开语法:
[...$a, ...$b],语义清晰、性能略好于array_merge(),但仅支持一维数值索引数组(不支持关联键)



















