Магия пустого контейнера: как заставить 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 операций (выгоднее, чем три отдельных вызова[]).