Menu

PHP array_merge(): объединение двух и более массивов

array_merge($a, $b) объединяет массивы в один: значения с числовыми ключами добавляются в конец и перенумеровываются, а для строковых ключей побеждает более поздний массив. Чем array_merge отличается от оператора + и распаковки [...$a, ...$b], как объединить список массивов и когда лучше подходят array_merge_recursive или array_replace.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

array_merge($a, $b) возвращает новый массив, где за элементами $a идут элементы $b. Числовые ключи перенумеровываются с 0; когда в обоих массивах есть один и тот же строковый ключ, побеждает значение из более позднего массива. Передавать можно сколько угодно массивов.

array_merge() не меняет свои аргументы. Она возвращает объединённый массив, поэтому присваивайте результат: $all = array_merge($all, $more);.

Числовые ключи перенумеровываются

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

Строковые ключи, похожие на целые числа ('101'), хранятся как целые, поэтому тоже перенумеровываются. Ключи вроде 'id101' остаются как есть.

array_merge и оператор +

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

array_merge($a, $b)$a + $b
Одинаковый строковый ключзначение из $bзначение из $a
Целочисленные ключиперенумерованы, все значения сохраненысохранены, $b проигрывает при совпадении
Типичное применениеобъединение списков, переопределение настроекподстановка значений по умолчанию, сохранение ID

Последний пример в блоке это классическая ловушка +: ['a', 'b'] + ['x', 'y', 'z'] даёт a, b, z, потому что ключи 0 и 1 уже есть слева.

Распаковка: [...a,...a, ...b]

Оператор распаковки разворачивает массивы внутри литерала массива. Он ведёт себя как array_merge(): целочисленные ключи перенумеровываются, а начиная с PHP 8.1 допускаются строковые ключи, и побеждает более поздний. Он хорошо читается, когда массивы смешиваются с отдельными значениями.

Чтобы дописать массив к существующему на месте, смотрите array_push() с оператором распаковки.

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

Когда объединяемые массивы сами лежат в списке, распакуйте этот список в array_merge(). Это ещё и быстрый способ объединять в цикле: соберите части, потом объедините один раз.

Запись $all = array_merge($all, $batch); внутри цикла работает, но на каждом проходе копирует весь растущий массив, и на тысячах элементов это становится медленно.

array_merge_recursive и array_replace

array_merge_recursive() объединяет и вложенные массивы, но для одинакового строкового ключа с простыми значениями не перезаписывает их, а собирает оба значения в новый массив. Для настроек это редко то, что нужно. Там обычно правильный инструмент array_replace_recursive(): она перезаписывает значения на всех уровнях и сохраняет ключи.

Прочитайте три строки JSON сверху вниз: array_merge() заменила весь массив db и потеряла host, array_merge_recursive() превратила port и debug в списки из двух элементов, а array_replace_recursive() дала ту конфигурацию, которую вы имели в виду.

Частая ошибка: слияние ничего не удаляет

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

Удаление дубликатов из строк и вложенных массивов описано на странице про array_unique.

Часто задаваемые вопросы

Чем array_merge отличается от + в PHP?

Для одинаковых строковых ключей array_merge($a, $b) оставляет значение из $b, а $a + $b оставляет значение из $a. Для числовых ключей array_merge() добавляет всё в конец и перенумеровывает, а + сохраняет числовые ключи и отбрасывает элементы $b, ключ которых уже есть в $a.

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

Используйте $a + $b, если должен побеждать левый массив, или array_replace($a, $b), если правый. array_merge() всегда перенумеровывает числовые ключи с 0.

Как объединить массив массивов в PHP?

Распакуйте внешний массив в array_merge(): $all = array_merge(...$lists);. Для пустого списка функция вернёт []. Сначала соберите массивы в цикле, а объединяйте один раз в конце; вызов array_merge() внутри цикла каждый раз копирует растущий результат.

Можно ли использовать оператор распаковки со строковыми ключами в PHP?

Да, начиная с PHP 8.1. [...$a, ...$b] тогда ведёт себя как array_merge($a, $b): числовые ключи перенумеровываются, а более поздний строковый ключ перезаписывает более ранний.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ