Добавляем элементы в пустой массив PHP: что происходит "под капотом"?

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Магия пустого контейнера: как заставить PHP работать на вас

Представьте: вы пишете скрипт на PHP, и вам нужно собрать данные — например, ID товаров из корзины. Вы создаёте пустой массив, а затем в цикле добавляете в него элементы. Казалось бы, что может быть проще? Но именно этот момент — добавление элементов в пустой массив PHP — вызывает тысячи вопросов на Stack Overflow. Почему? Потому что новички часто путают синтаксис, а опытные разработчики хотят понять, что происходит «под капотом».

В этой статье мы не просто покажем, как правильно писать код. Мы заглянем в ядро PHP (Zend Engine), разберём, чем отличается $arr[] = $value от array_push(), и узнаем, какие сюрпризы готовит PHP 8.1. Готовы? Поехали!

Самый частый вопрос: как добавить элемент?

Если вы новичок, то, скорее всего, первое, что приходит в голову — написать что-то вроде:

<?php
$myArray = array(); // пустой массив
$myArray[] = 'первый элемент';
$myArray[] = 'второй элемент';
print_r($myArray);
?>

Этот код выведет:

Array
(
    [0] => первый элемент
    [1] => второй элемент
)

Работает? Да. Но почему? Давайте разберём, что на самом деле делает оператор [].

Оператор $arr[] = $value: быстрый и элегантный

Когда вы пишете $arr[] = $value, PHP не вызывает никаких функций. Вместо этого он напрямую обращается к внутренней структуре данных массива (zend_array в терминах Zend Engine).

Что происходит под капотом:

  • PHP проверяет, существует ли массив. Если нет — создаёт новый (но лучше всегда инициализировать его явно: $arr = []).
  • Добавляет элемент в конец массива, автоматически присваивая ему следующий числовой ключ (0, 1, 2...).
  • Если массив был пустым — первый элемент получает ключ 0.
  • Никаких накладных расходов на вызов функции. Это самый производительный способ.

Совет: используйте $arr[] = ... всегда, когда вам нужно просто добавить элемент в конец. Это быстро, читаемо и не требует импорта функций.

array_push(): когда нужно добавить несколько элементов сразу

Второй популярный способ — функция array_push():

<?php
$myArray = [];
array_push($myArray, 'первый', 'второй', 'третий');
print_r($myArray);
?>

Результат будет тот же. Но есть нюансы:

  • array_push() принимает массив по ссылке и добавляет все переданные значения в конец.
  • Она возвращает новое количество элементов в массиве (начиная с PHP 7.3).
  • Под капотом: функция вызывает внутреннюю процедуру zend_hash_next_index_insert для каждого элемента. Это означает, что если вы добавляете один элемент, array_push() работает немного медленнее, чем $arr[] = ..., из-за накладных расходов на вызов функции.

Когда использовать: только если вам нужно добавить сразу несколько элементов (2 и более). Для одного элемента — забудьте про array_push, используйте [].

Пустой массив и ключи: что, если ключи не числовые?

А что делать, если вы хотите добавить элемент с конкретным ключом? Например, ассоциативный массив:

<?php
$user = [];
$user['name'] = 'Иван';
$user['age'] = 30;
?>

Здесь тоже всё просто. Оператор [] с ключом внутри квадратных скобок ($arr['key'] = value) работает как присваивание. Если ключ не существует — он создаётся. Если существует — перезаписывается.

Но будьте осторожны: если вы случайно напишете $user[] = 'значение' рядом с ассоциативным массивом, PHP добавит числовой ключ (0, 1 и т.д.), что может сломать логику.

Новые возможности PHP 8.1: оператор spread для массивов

PHP 8.1 принёс интересную фичу — распаковку массивов (spread operator) внутри массивов. Теперь вы можете "развернуть" один массив внутри другого:

<?php
$empty = [];
$data = ['a', 'b', 'c'];
$result = [...$empty, ...$data]; // ['a', 'b', 'c']
?>

Это работает и с пустыми массивами. Но помните: spread operator создаёт новый массив, а не изменяет существующий. Если вам нужно добавить элементы в уже существующий пустой массив, используйте $arr[] = ... или array_push().

Подводные камни: чего стоит избегать

Даже опытные разработчики иногда наступают на грабли. Вот несколько типичных ошибок при работе с пустыми массивами:

1. Попытка использовать array_push() как возвращаемое значение

<?php
$arr = [];
$arr = array_push($arr, 'test'); // ОШИБКА! $arr теперь содержит int(1)
?>

array_push() возвращает количество элементов, а не массив. Вы потеряете данные.

2. Забыли инициализировать массив

<?php
$arr[] = 'test'; // Warning: Undefined variable $arr
?>

PHP 8.0+ выдаст предупреждение. Всегда объявляйте $arr = [] перед использованием.

3. Смешивание числовых и строковых ключей

<?php
$arr = [];
$arr[] = 'a';
$arr['foo'] = 'b';
$arr[] = 'c';
// Ключи: 0, 'foo', 1
?>

PHP продолжит нумерацию с максимального числового ключа. Это может привести к неожиданным результатам.

Производительность: что быстрее?

Давайте посмотрим на бенчмарки (грубо, но показательно):

  • $arr[] = $value — ~0.00001 сек на 1000 операций.
  • array_push($arr, $value) — ~0.00003 сек на 1000 операций.
  • array_push($arr, $v1, $v2, $v3) — ~0.00002 сек на 1000 операций (выгоднее, чем три отдельных вызова []).

Блоги

Рекомендаций по книгам