php, array_merge_recursive 仅适用于字符串键

Joh*_*ith 3 php

$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 键是相同的

Ste*_*ant 5

让我们把这个问题分解成单独的问题:

  1. 当第二个数组中的键存在于第一个数组中时,您希望创建一个数组并使该值成为该数组的第一个元素。

老实说,我不知道解决这个问题的简单方法。我不确定有没有。即使,我也不确定你是否真的想要它。这样的函数将导致数组的值是字符串数组。你会如何处理这样的数组?

更新:嗯,有一个。您的示例已经显示array_merge_recursive将带有字符串键的值转换为数组。所以1 => 'foo'0 => 'foo',但'foo' => 'bar'最终会为'foo' => ['bar']。我真的不明白这种行为。

在这种情况下,使用字符串键可以帮助您解决问题,但在了解更多信息后,array_merge_recursive我决定尽可能避免使用此功能。在我问了这个问题之后,有人把它作为一个bug 从 PHP 7.0 开始,因为它在 PHP 5.x 中的工作方式不同。

  1. 你想保留键,虽然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 的强项,您可以将其视为小问题。