$array1 = [
'1' => '11',
'b' => 1,
3 => 33,
8 => 8
];
$array2 = [
'1' => '22',
'b' => 2,
3 => 44,
9 => 9
];
$merged = array_merge_recursive($array1, $array2);
Run Code Online (Sandbox Code Playgroud)
结果是:
array(7) {
[0]=>
string(2) "11"
["b"]=>
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
[1]=>
int(33)
[2]=>
int(8)
[3]=>
string(2) "22"
[4]=>
int(44)
[5]=>
int(9)
}
Run Code Online (Sandbox Code Playgroud)
所以让我们看一眼:唯一的部分是'b'钥匙,它们实际上是有效的。我不想覆盖它的任何内容,而是将它们放在一个数组中。那挺好的!但是其他数字键(整数或字符串)的键被搞砸了。我想得到这个结果:
[
'1' => ['11', '22']
'b' => [1, 2]
[3] => [33, 44]
[8] => 8,
[9] => 9
]
Run Code Online (Sandbox Code Playgroud)
可能的?
编辑:当然键 "1" 和 1 - string vs int 键是相同的
让我们把这个问题分解成单独的问题:
老实说,我不知道解决这个问题的简单方法。我不确定有没有。即使,我也不确定你是否真的想要它。这样的函数将导致数组的值是字符串或数组。你会如何处理这样的数组?
更新:嗯,有一个。您的示例已经显示array_merge_recursive将带有字符串键的值转换为数组。所以1 => 'foo'会0 => 'foo',但'foo' => 'bar'最终会为'foo' => ['bar']。我真的不明白这种行为。
在这种情况下,使用字符串键可以帮助您解决问题,但在了解更多信息后,array_merge_recursive我决定尽可能避免使用此功能。在我问了这个问题之后,有人把它作为一个bug 从 PHP 7.0 开始,因为它在 PHP 5.x 中的工作方式不同。
array_merge_resursive不保留整数键,而它保留整数键:如果输入数组具有相同的字符串键,则将这些键的值合并到一个数组中,这是递归完成的,因此如果其中一个值是数组本身,则函数会将其与相应的条目合并在另一个数组中。但是,如果数组具有相同的数字键,则后面的值不会覆盖原始值,而是会附加。
更糟糕的是,它在处理嵌套数组时的处理方式不同:
$array1 = [30 => [500 => 'foo', 600 => 'bar']];
$array2 = [];
array_merge_recursive($array1, $array2);
//[0 => [500=> 'foo', 600 => 'bar']];
Run Code Online (Sandbox Code Playgroud)
如此有效,array_merge_resursive并不是真正的resurive。
使用array_replace_resursive解决了这个问题:
array_replace_recursive($array1, $array2);
//output:
//array:5 [
// 1 => "22"
// "b" => 2
// 3 => 44
// 8 => 8
// 9 => 9
//]
Run Code Online (Sandbox Code Playgroud)
请注意,PHP 在不一致方面非常一致。虽然array_merge_recursive不是递归的,array_replace_recursive但不替换(它也附加):
如果键存在于第二个数组中,而不是第一个数组中,它将在第一个数组中创建。
在许多情况下,这是期望的行为,因为命名函数不是 PHP 的强项,您可以将其视为小问题。