array_merge_recursive() 能递归合并多层数组,相同键的值会保留并形成新数组,适用于深度合并配置或嵌套数据,而 array_merge() 会直接覆盖同名键,适合扁平结构合并。

在PHP中,合并多个数组是日常开发中非常普遍的需求。当我们面对需要深度合并、尤其是包含多层嵌套数组的场景时,
array_merge_recursive()
array_merge_recursive()
当你传入多个数组给
array_merge_recursive()
[0 => 'a']
[0 => 'b']
[0 => 'a', 1 => 'b']
['key' => 'value1']
['key' => 'value2']
['key' => ['value1', 'value2']]
['key' => ['value1']]
['key' => 'value2']
['key' => ['value1', 'value2']]
来看个具体的例子,这样理解起来更直观:
立即学习“PHP免费学习笔记(深入)”;
<?php
$array1 = [
'name' => 'Alice',
'options' => [
'color' => 'red',
'size' => 'M'
],
'tags' => ['PHP', 'Web']
];
$array2 = [
'name' => 'Bob',
'options' => [
'size' => 'L',
'material' => 'cotton'
],
'tags' => ['CSS', 'Web'],
'new_field' => 'value'
];
$array3 = [
'options' => [
'color' => 'blue',
'type' => 'hoodie'
],
'tags' => 'JavaScript' // 注意这里是一个字符串,不是数组
];
$mergedArray = array_merge_recursive($array1, $array2, $array3);
print_r($mergedArray);
?>输出结果会是这样:
Array
(
[name] => Array
(
[0] => Alice
[1] => Bob
)
[options] => Array
(
[color] => Array
(
[0] => red
[1] => blue
)
[size] => Array
(
[0] => M
[1] => L
)
[material] => cotton
[type] => hoodie
)
[tags] => Array
(
[0] => PHP
[1] => Web
[2] => CSS
[3] => Web
[4] => JavaScript
)
[new_field] => value
)从这个结果能看出来,
name
options
color
size
material
type
tags
'JavaScript'
array_merge()
array_merge_recursive()
这个问题是很多PHP开发者初学数组合并时都会遇到的“坎儿”。说实话,一开始我也经常混淆,毕竟名字太像了。但它们的核心差异在于如何处理冲突的字符串键以及是否进行递归合并。
array_merge()
<?php $arrA = ['id' => 1, 'data' => ['a' => 1]]; $arrB = ['id' => 2, 'data' => ['b' => 2]]; $merged = array_merge($arrA, $arrB); print_r($merged); // 输出:Array ( [id] => 2 [data] => Array ( [b] => 2 ) ) // 注意,data键被完全覆盖了,arrA中的['a' => 1]丢失了。 ?>
array_merge_recursive()
array_merge()
<?php $arrA = ['id' => 1, 'data' => ['a' => 1]]; $arrB = ['id' => 2, 'data' => ['b' => 2]]; $mergedRecursive = array_merge_recursive($arrA, $arrB); print_r($mergedRecursive); // 输出:Array ( [id] => Array ( [0] => 1 [1] => 2 ) [data] => Array ( [a] => 1 [b] => 2 ) ) // 这里id被合并成了一个数组,data内部的a和b也被保留了。 ?>
总结一下,如果你的数组结构是扁平的,或者你明确知道后面数组的值应该覆盖前面数组的值,用
array_merge()
array_merge_recursive()
array_merge_recursive()
我们来详细看看几种常见的冲突情况:
字符串键,值一个是标量,另一个也是标量: 这是最常见的情况。例如:
$arr1 = ['key' => 'value1'];
$arr2 = ['key' => 'value2'];
array_merge_recursive($arr1, $arr2)
['key' => ['value1', 'value2']]
字符串键,值一个是数组,另一个是标量: 这种场景也挺多。
$arr1 = ['key' => ['sub_key' => 'sub_value1']];
$arr2 = ['key' => 'value2'];
array_merge_recursive($arr1, $arr2)
['key' => ['sub_key' => 'sub_value1', 0 => 'value2']]
字符串键,值都是数组: 这是
array_merge_recursive()
$arr1 = ['key' => ['sub_key1' => 'value1']];
$arr2 = ['key' => ['sub_key2' => 'value2']];
array_merge_recursive($arr1, $arr2)
['key' => ['sub_key1' => 'value1', 'sub_key2' => 'value2']]
实际应用中的思考:
这种处理方式的优点是信息不丢失,所有冲突的值都被保留了下来。但缺点也很明显,它可能会导致结果数组的结构变得复杂,尤其是当标量值被“强制”塞进数组时。你可能需要编写额外的逻辑来处理这些新生成的数值键,或者在合并后对数组进行清理。
举个例子,假设你正在合并用户设置:
<?php $defaultSettings = ['theme' => 'light', 'permissions' => ['read' => true, 'write' => false]]; $userSettings = ['theme' => 'dark', 'permissions' => 'admin']; // 用户不小心把permissions设成了字符串 $finalSettings = array_merge_recursive($defaultSettings, $userSettings); print_r($finalSettings); ?>
结果会是:
Array
(
[theme] => Array
(
[0] => light
[1] => dark
)
[permissions] => Array
(
[read] => 1
[write] =>
[0] => admin
)
)你看,
theme
permissions
array_merge_recursive()
array_replace_recursive()
array_merge_recursive()
PHP在数组操作上确实提供了不少工具,除了
array_merge_recursive()
+
<?php $defaultOptions = ['timeout' => 30, 'cache' => true, 'mode' => 'strict']; $userOptions = ['cache' => false, 'retries' => 3]; $finalOptions = $userOptions + $defaultOptions; // 注意顺序,右边的元素会补充左边 print_r($finalOptions); // 输出:Array ( [cache] => false [retries] => 3 [timeout] => 30 [mode] => strict ) // userOptions中的cache覆盖了defaultOptions,而retries被添加,timeout和mode则保留了defaultOptions的值。 ?>
array_replace()
array_replace_recursive()
array_merge()
array_merge_recursive()
array_replace()
array_merge()
null
array_merge()
<?php $arr1 = ['a' => 1, 'b' => 2]; $arr2 = ['a' => 10, 'c' => 3]; $replaced = array_replace($arr1, $arr2); print_r($replaced); // 输出:Array ( [a] => 10 [b] => 2 [c] => 3 ) // a被替换,c被添加。 ?>
array_replace_recursive()
array_merge_recursive()
array_merge_recursive()
<?php
$configDefaults = [
'database' => ['host' => 'localhost', 'port' => 3306],
'logging' => ['level' => 'info']
];
$userConfig = [
'database' => ['port' => 5432], // 只想改端口
'logging' => ['level' => 'debug', 'file' => '/var/log/app.log']
];
$finalConfig = array_replace_recursive($configDefaults, $userConfig);
print_r($finalConfig);
// 输出:
// Array
// (
// [database] => Array
// (
// [host] => localhost
// [port] => 5432 // port被替换了,host保留
// )
// [logging] => Array
// (
// [level] => debug // level被替换
// [file] => /var/log/app.log // file被添加
// )
// )
?>可以看到,
array_replace_recursive()
array_merge_recursive()
手动循环合并 在某些非常复杂或需要高度定制的合并逻辑时,上述函数可能无法满足需求。例如,你可能需要根据某个条件来决定是否合并某个键,或者在合并时对值进行转换。
foreach
选择哪种合并方式,真的取决于你的具体需求:是想要保留所有冲突的值,还是希望新的值覆盖旧的值?是只处理第一层,还是要深入到嵌套数组?理解这些函数的细微差别,能帮助你更有效地处理PHP中的数组操作,避免一些常见的“坑”。
以上就是如何在PHP中合并多个数组?array_merge_recursive()的用法解析的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号