W3docs

Функция PHP: array_merge_recursive

Функция array_merge_recursive в PHP объединяет массивы, сохраняя все значения при совпадении строковых ключей.

Функция array_merge_recursive() в PHP объединяет два или более массива в один. Её отличительная особенность — обработка совпадающих строковых ключей: вместо того чтобы позволять более позднему значению перезаписывать более раннее, она объединяет оба значения в подмассив, рекурсивно обходя вложенные массивы. Это делает её подходящим инструментом, когда нужно сохранить каждое значение, а не оставить только значение из последнего массива.

На этой странице рассматриваются синтаксис и параметры, принцип работы рекурсивного слияния, отличия от array_merge(), реальный пример использования и подводные камни, о которых стоит знать.

Синтаксис

array_merge_recursive(array $array1, array ...$arrays): array

Параметры

  • array1: Первый входной массив.
  • ...$arrays: Один или несколько дополнительных массивов для слияния.

Возвращаемое значение

Возвращает результирующий объединённый массив.

Как работает array_merge_recursive?

Функция применяет два разных правила в зависимости от типа ключа:

  • Строковые ключи, встречающиеся более чем в одном массиве, объединяются. Если оба значения являются скалярными, они помещаются в новый подмассив; если оба являются массивами, функция рекурсивно обходит их и объединяет на следующем уровне.
  • Целочисленные (числовые) ключи никогда не перезаписываются. Каждый элемент с числовым ключом добавляется в конец и перенумеровывается, так что ничего не теряется, а результат переиндексируется начиная с 0.

Вот почему функция называется «рекурсивной»: при обнаружении двух массивов под одним строковым ключом она углубляется в них и повторяет ту же логику слияния для их содержимого.

Примечание: В отличие от array_merge(), которая перезаписывает значения при совпадении строковых ключей и переиндексирует числовые ключи, array_merge_recursive() объединяет совпадающие строковые ключи во вложенные массивы, сохраняя каждое значение.

Вот пример того, как работает array_merge_recursive:

Пример PHP: функция array_merge_recursive

php— editable, runs on the server

Вывод этого кода будет следующим:

Array
(
    [color] => Array
        (
            [favorite] => Array
                (
                    [0] => red
                    [1] => green
                )
            [0] => blue
        )
    [0] => 5
    [1] => 10
)

Как видно, функция array_merge_recursive объединила совпадающие ключи входных массивов в подмассивы.

array_merge() vs. array_merge_recursive()

Сравнение двух функций бок о бок наглядно демонстрирует разницу:

<?php

$defaults  = ["roles" => ["user"],   "name" => "Guest"];
$overrides = ["roles" => ["editor"], "name" => "Ann"];

print_r(array_merge($defaults, $overrides));
print_r(array_merge_recursive($defaults, $overrides));

?>
Array                       // array_merge(): later value wins
(
    [roles] => Array
        (
            [0] => editor
        )
    [name] => Ann
)
Array                       // array_merge_recursive(): both values kept
(
    [roles] => Array
        (
            [0] => user
            [1] => editor
        )
    [name] => Array
        (
            [0] => Guest
            [1] => Ann
        )
)

Обратите внимание: даже name, простая строка, превратилась в массив ["Guest", "Ann"]. Это ключевой подводный камень, описанный ниже: рекурсивное слияние превращает каждый повторяющийся строковый ключ в список, хотите вы того или нет.

Когда использовать array_merge_recursive

Используйте эту функцию, когда цель — собрать значения, а не выбирать одно из них. Распространённый случай — группировка данных, например построение карты категорий и всех относящихся к ним элементов:

<?php

$result = [];
$products = [
    ["category" => "fruit",     "name" => "apple"],
    ["category" => "fruit",     "name" => "pear"],
    ["category" => "vegetable", "name" => "carrot"],
];

foreach ($products as $product) {
    $result = array_merge_recursive(
        $result,
        [$product["category"] => [$product["name"]]]
    );
}

print_r($result);

?>
Array
(
    [fruit] => Array
        (
            [0] => apple
            [1] => pear
        )
    [vegetable] => Array
        (
            [0] => carrot
        )
)

Подводные камни

  • Строковые ключи объединяются, целочисленные — добавляются. Повторяющийся строковый ключ порождает подмассив, даже если оба значения являются скалярными. Если нужно, чтобы более поздние значения перезаписывали более ранние, используйте array_merge() или array_replace_recursive().
  • Числовые ключи не сохраняются. Целочисленные ключи всегда перенумеровываются начиная с 0, поэтому нельзя использовать array_merge_recursive() для слияния двух массивов по их числовым ключам. Используйте оператор + (объединение), если необходимо сохранить ключи как есть.
  • Функция спускается только в массивы. Если одна сторона является скаляром, а другая — массивом под тем же ключом, оба просто собираются в список; скаляр не вливается внутрь массива.

Связанные функции

  • array_merge() — плоское слияние, при котором более поздние строковые ключи перезаписывают более ранние.
  • array_replace_recursive() — рекурсивный обход, как в данной функции, но со заменой значений вместо их накопления.
  • array_combine() — создаёт массив из отдельного массива ключей и массива значений.

Заключение

Функция array_merge_recursive() — правильный выбор, когда нужно объединить значения для общих строковых ключей, а не перезаписывать их: при группировке, агрегации или накоплении данных из нескольких массивов. Помните о двух правилах (строковые ключи объединяются в списки, целочисленные — переиндексируются) и выбирайте array_merge() или array_replace_recursive(), когда нужно поведение «побеждает последнее значение».

Практика

Практика
Что делает функция array_merge_recursive() в PHP?
Что делает функция array_merge_recursive() в PHP?
Was this page helpful?