Слияние массивов в PHP: полное руководство

Раздел: PHP -> Массивы

Объединение массивов в PHP: способы и особенности

Слияние массивов - одна из частых операций при работе с данными. В PHP существует несколько подходов, каждый из которых подходит для определённых сценариев. В этом материале рассмотрены основные методы, их преимущества и потенциальные ошибки.

Наиболее универсальное решение: array_merge

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


$arr1 = ['a' => 1, 'b' => 2];
$arr2 = ['b' => 3, 'c' => 4];
$result = array_merge($arr1, $arr2);
// $result = ['a' => 1, 'b' => 3, 'c' => 4]

Числовые ключи будут перенумерованы с нуля, поэтому предыдущие индексы теряются.

Типичная ошибка: при слиянии массивов с числовыми ключами теряются исходные индексы, что может привести к непредсказуемому порядку. Если требуется сохранить числовые ключи, используйте оператор +.

Как объединить массивы без перезаписи существующих ключей?

Оператор + добавляет элементы второго массива только тогда, когда ключ отсутствует в первом. При этом числовые ключи считаются строковыми (не переиндексируются).


$arr1 = [0 => 'apple', 1 => 'banana'];
$arr2 = [0 => 'cherry', 2 => 'date'];
$result = $arr1 + $arr2;
// $result = [0 => 'apple', 1 => 'banana', 2 => 'date']

Проблема: при совпадении строковых ключей значение из первого массива остаётся, что может быть неочевидно.

Как рекурсивно объединить вложенные массивы?

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


$arr1 = ['color' => ['r' => 255]];
$arr2 = ['color' => ['g' => 128]];
$result = array_merge_recursive($arr1, $arr2);
// $result = ['color' => ['r' => 255, 'g' => 128]]

Ошибка: если на одном уровне встречаются строковый ключ и числовой, результат может быть неожиданным.

Как объединить массивы с использованием spread-оператора?

Начиная с PHP 7.4 (для ассоциативных массивов с PHP 8.1) можно использовать ... внутри литерала массива. Работает аналогично array_merge.


$arr1 = ['x' => 10];
$arr2 = ['y' => 20];
$result = [...$arr1, ...$arr2];
// $result = ['x' => 10, 'y' => 20]

Ограничение: spread не поддерживает многомерное рекурсивное слияние и может быть медленнее на больших массивах.

Как заменить значения при совпадении ключей?

array_replace замещает значения первого массива значениями второго при совпадении ключей (как строковых, так и числовых).


$arr1 = ['a' => 1, 'b' => 2];
$arr2 = ['a' => 3, 'c' => 4];
$result = array_replace($arr1, $arr2);
// $result = ['a' => 3, 'b' => 2, 'c' => 4]

Различие с array_merge: числовые ключи не переиндексируются, что может быть неудобно при работе с пронумерованными списками.

Как добавить элементы в конец массива?

Для простого добавления одного или нескольких элементов используется array_push.


$fruits = ['apple'];
array_push($fruits, 'banana', 'cherry');
// $fruits = ['apple', 'banana', 'cherry']

Для слияния нескольких массивов array_push не подходит - он добавит второй массив как вложенный.

Ошибка: передача массива вторым аргументом в array_push поместит его целиком, а не раскроет элементы.

Как вручную объединить массивы через цикл?

Для полного контроля над процессом можно использовать foreach.


$merged = [];
foreach ([$arr1, $arr2] as $arr) {
    foreach ($arr as $key => $value) {
        $merged[$key] = $value; // перезапись или добавление
    }
}

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

Расширенные примеры объединения массивов

Слияние нескольких массивов с разными типами ключей

Пример

$arr1 = ['name' => 'Alice', 0 => 'admin'];
$arr2 = [1 => 'editor', 'name' => 'Bob'];
$arr3 = ['role' => 'user'];

// array_merge переиндексирует числовые ключи
$merged = array_merge($arr1, $arr2, $arr3);
print_r($merged);
Array
(
    [name] => Bob        # перезапись строкового ключа
    [0] => admin
    [1] => editor
    [role] => user
)

Числовые ключи 0 и 1 из первого массива смешались с ключами второго, порядок может сбить с толку.

Использование оператора + для сохранения оригинальных индексов

Пример

$arr1 = [0 => 'red', 1 => 'green'];  // индексы 0 и 1
$arr2 = [0 => 'blue', 2 => 'yellow'];
$result = $arr1 + $arr2;
print_r($result);
Array
(
    [0] => red
    [1] => green
    [2] => yellow
)

Первое значение при совпадении числовых ключей не заменяется.

Рекурсивное слияние с array_merge_recursive на трёх уровнях вложенности

Пример

$deep1 = ['config' => ['db' => ['host' => 'localhost']]];
$deep2 = ['config' => ['db' => ['port' => 3306, 'user' => 'root']]];
$deep3 = ['config' => ['app' => ['debug' => true]]];

$merged = array_merge_recursive($deep1, $deep2, $deep3);
print_r($merged);
Array
(
    [config] => Array
        (
            [db] => Array
                (
                    [host] => localhost
                    [port] => 3306
                    [user] => root
                )
            [app] => Array
                (
                    [debug] => 1
                )
        )
)

Ключи объединились рекурсивно, значения не перезаписываются.

Слияние с заменой через array_replace при числовых ключах

Пример

$base = [0 => 'one', 1 => 'two', 2 => 'three'];
$override = [1 => 'TWO', 3 => 'four'];

$result = array_replace($base, $override);
print_r($result);
Array
(
    [0] => one
    [1] => TWO
    [2] => three
    [3] => four
)

Числовые ключи не переиндексируются, индекс 1 заменён, добавлен новый ключ 3.

Spread-оператор с ассоциативными и числовыми ключами (PHP 8.1+)

Пример

$colors = ['red', 'green'];
$more = ['blue', 'yellow'];
$combined = [...$colors, ...$more];
print_r($combined);
Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => yellow
)

Для ассоциативных массивов spread ведёт себя как array_merge.

Комбинация array_merge и array_map для обработки перед слиянием

Пример

$arrays = [
    ['a' => 1, 'b' => 2],
    ['a' => 3, 'c' => 4],
    ['b' => 5, 'd' => 6]
];

$processed = array_map(function($arr) {
    return array_filter($arr, fn($v) => $v > 2);
}, $arrays);

$flatten = array_merge(...$processed);
print_r($flatten);
Array
(
    [a] => 3
    [c] => 4
    [b] => 5
    [d] => 6
)

Сначала отфильтрованы значения, затем массивы слиты в один.

Объединение массивов с помощью array_push в цикле (не рекомендуется)

Пример

$result = ['x' => 1];
$extra = ['y' => 2, 'z' => 3];
foreach ($extra as $key => $value) {
    $result[$key] = $value;
}
print_r($result);
Array
(
    [x] => 1
    [y] => 2
    [z] => 3
)

Ручной цикл даёт полный контроль, но менее выразителен.

Объединение массивов в PHP - comments

En
Php объединить массивы (php)