Array merge: примеры (PHP)

Руководство по работе с array_merge в PHP
Раздел: Работа с массивами
array_merge(array ...$arrays): array

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

Применение

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

Аргументы

Функция принимает переменное количество аргументов:

  • array1 (array) - Первый массив.
  • array2 (array, опционально) - Второй массив.
  • ... (array, опционально) - Дополнительные массивы для слияния.

Начиная с PHP 7.4, функция поддерживает оператор распаковки ... для объединения массивов, переданных в виде переменной.

Базовые примеры демонстрируют основную логику работы функции.

Простое слияние

Объединение двух массивов с числовыми ключами:

$array1 = ["a", "b"];
$array2 = ["c", "d"];
$result = array_merge($array1, $array2);
print_r($result);
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)
Слияние с строковыми ключами

Если ключи строковые и повторяются, последнее значение перезаписывает предыдущее:

$array1 = ["color" => "red", 2, 4];
$array2 = ["a", "b", "color" => "green", "shape" => "trapezoid", 4];
$result = array_merge($array1, $array2);
print_r($result);
Array
(
    [color] => green
    [0] => 2
    [1] => 4
    [2] => a
    [3] => b
    [shape] => trapezoid
    [4] => 4
)
Объединение с числовыми ключами

Числовые ключи переиндексируются, начиная с нуля в результирующем массиве:

$array1 = [2 => "data1", 5 => "data2"];
$array2 = [1 => "data3", 8 => "data4"];
$result = array_merge($array1, $array2);
print_r($result);
Array
(
    [0] => data1
    [1] => data2
    [2] => data3
    [3] => data4
)

В PHP существуют другие функции для работы с массивами, которые могут быть полезны в конкретных сценариях.

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

array_replace и array_replace_recursive

Функция array_replace заменяет элементы первого массива элементами из переданных массивов. Для строковых ключей работает как перезапись, а числовые ключи не переиндексируются, значение просто заменяется. Рекурсивная версия работает аналогично для многомерных массивов.

Оператор +

Оператор объединения массивов + возвращает левый массив, дополненный элементами из правого. Ключи, которые уже существуют в левом массиве, не перезаписываются. Это ключевое отличие от array_merge, где значения с одинаковыми строковыми ключами перезаписываются, а числовые переиндексируются.

$a = ['a' => 'apple', 'b' => 'banana'];
$b = ['a' => 'apricot', 'c' => 'cherry'];
$result = $a + $b; // 'a' останется 'apple'
print_r($result);
Array
(
    [a] => apple
    [b] => banana
    [c] => cherry
)

При работе с функцией можно столкнуться с несколькими типичными ситуациями.

Передача аргументов, не являющихся массивами

До PHP 8.0 это вызывало ошибку уровня E_WARNING. Начиная с PHP 8.0, выбрасывается исключение TypeError.

// PHP 7.x
$result = array_merge([1, 2], 'not_array'); // Warning
// PHP 8.0+
// $result = array_merge([1, 2], 'not_array'); // TypeError
Неожиданная переиндексация числовых ключей

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

$defaults = [100 => 'default_value'];
$userData = [100 => 'user_value'];
$config = array_merge($defaults, $userData);
// Ожидание: [100 => 'user_value']
// Реальность: [0 => 'default_value', 1 => 'user_value']
print_r($config);
Array
(
    [0] => default_value
    [1] => user_value
)
Слияние многомерных массивов

Функция array_merge не выполняет рекурсивное слияние. Внутренние массивы сливаются по тем же правилам, что может привести к неполному объединению вложенных структур.

$array1 = ['settings' => ['theme' => 'light']];
$array2 = ['settings' => ['language' => 'en']];
$result = array_merge($array1, $array2);
print_r($result);
Array
(
    [settings] => Array
        (
            [language] => en
        )
)

Ключ settings был полностью перезаписан вторым массивом. Для глубокого слияния нужна array_merge_recursive.

Поведение функции менялось с развитием языка PHP.

PHP 7.4

Появилась возможность использовать оператор распаковки ... в качестве аргумента для слияния массива массивов. Это сделало код чище.

$arrays = [[1, 2], [3, 4], [5, 6]];
$result = array_merge(...$arrays); // Работает в PHP 7.4+
print_r($result);
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
)
PHP 8.0

Наиболее значимое изменение: функция теперь выбрасывает исключение TypeError, если какой-либо из переданных аргументов не является массивом. Ранее выдавалось предупреждение (E_WARNING), и функция продолжала работу, пропуская неверный аргумент. Это повышает строгость типизации.

Рассмотрим более сложные и специальные случаи применения.

Объединение с оператором распаковки (PHP 7.4+)

Удобно для динамического набора массивов.

Пример php
function mergeConfigs(array ...$configs): array {
    return array_merge(...$configs);
}

$cfg1 = ['host' => 'localhost'];
$cfg2 = ['port' => 3306];
$cfg3 = ['charset' => 'utf8mb4'];

$finalConfig = mergeConfigs($cfg1, $cfg2, $cfg3);
print_r($finalConfig);
Array
(
    [host] => localhost
    [port] => 3306
    [charset] => utf8mb4
)
Создание массива с последовательными числовыми ключами из фрагментов

Полезно для переиндексации после фильтрации или удаления элементов.

Пример php
$fruits = [5 => 'apple', 10 => 'banana', 15 => 'cherry'];
$vegetables = [20 => 'carrot', 25 => 'potato'];

// После объединения ключи становятся 0,1,2,3,4
$produce = array_merge($fruits, $vegetables);
print_r($produce);
Array
(
    [0] => apple
    [1] => banana
    [2] => cherry
    [3] => carrot
    [4] => potato
)
Имитация добавления элементов в ассоциативный массив с гарантией перезаписи

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

Пример php
$baseQuery = ['page' => 1, 'sort' => 'name', 'filter' => 'all'];
$userOverride = ['page' => 5, 'filter' => 'active'];

$finalQuery = array_merge($baseQuery, $userOverride);
print_r($finalQuery);
Array
(
    [page] => 5
    [sort] => name
    [filter] => active
)
Объединение с пустыми и null значениями

Функция игнорирует аргументы, которые не являются массивами (в PHP 8.0+ это ошибка). Но пустые массивы - валидные аргументы.

Пример php
$result = array_merge(['a'], [], ['b']);
print_r($result);
Array
(
    [0] => a
    [1] => b
)
Сравнение с array_replace для числовых ключей

Важное отличие в поведении с числовой индексацией.

Пример php
$a = [2 => 'two', 3 => 'three'];
$b = [3 => 'NEW THREE', 4 => 'four'];

$mergeResult = array_merge($a, $b);
$replaceResult = array_replace($a, $b);

print_r($mergeResult);
print_r($replaceResult);
// array_merge
Array
(
    [0] => two
    [1] => three
    [2] => NEW THREE
    [3] => four
)
// array_replace
Array
(
    [2] => two
    [3] => NEW THREE
    [4] => four
)

В других языках существуют аналогичные операции для работы с коллекциями.

JavaScript

Метод concat() или оператор расширения ... объединяют массивы. Для объектов (аналог ассоциативных массивов) можно использовать Object.assign() или оператор расширения, где свойства перезаписываются.

// Оператор расширения
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]

// Для объектов
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const mergedObj = { ...obj1, ...obj2 }; // { a: 1, b: 3, c: 4 }

Array merge в Python

Для списков используется оператор + или метод extend(). Для словарей (dict) в версиях Python 3.5+ применяется оператор распаковки **, а также метод update(), который модифицирует исходный словарь.

# Списки
list1 = [1, 2]
list2 = [3, 4]
merged_list = list1 + list2  # [1, 2, 3, 4]

# Словари
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged_dict = {**dict1, **dict2}  # {'a': 1, 'b': 3, 'c': 4}
MySQL

Прямого аналога нет, но для объединения наборов строк из запросов используется оператор UNION или UNION ALL.

SELECT column1 FROM table1
UNION ALL
SELECT column1 FROM table2;

PHP array_merge function comments

En
Array merge Merge one or more arrays