Массивы в PHP — это как швейцарский нож: вроде бы все умеют им пользоваться, но мало кто знает, как выжать из него максимум. Если ты уже научился добавлять элементы, перебирать их циклом и считать длину, пора переходить на новый уровень. В этой статье я расскажу о техниках, которые делают код чище, быстрее и понятнее. Без лишней теории — только практика.

Зачем вообще париться с продвинутыми техниками?

Ты когда-нибудь писал такое:

$result = [];
foreach ($array as $item) {
    if ($item['active']) {
        $result[] = $item['name'];
    }
}

Вроде бы работает. Но есть нюанс: такой код раздувает файлы, его сложнее читать, и он медленнее выполняется на больших данных. Продвинутые функции массивов позволяют заменить 5-10 строк одной строкой. И это не магия — это стандартные инструменты PHP.

Лайфхак: если ты видишь цикл foreach, который что-то фильтрует или преобразует, смело заменяй его на array_filter или array_map. Это сделает код самодокументируемым.

Правило: Никогда не используй foreach для простых фильтраций или преобразований. Это признак кода новичка. Используй встроенные функции массивов — они быстрее и читаемее.

array_map: когда нужно преобразовать каждый элемент

Функция array_map применяет callback к каждому элементу массива и возвращает новый массив. Проще говоря, ты говоришь: «возьми каждый элемент, сделай с ним вот это, и верни результат».

Пример: превращаем массив чисел в массив их квадратов.

$numbers = [1, 2, 3, 4, 5];
$squares = array_map(fn($n) => $n * $n, $numbers);
// $squares = [1, 4, 9, 16, 25]

Обрати внимание на стрелочную функцию (arrow function) — она появилась в PHP 7.4 и делает код ещё короче. Если у тебя старая версия, используй анонимную функцию:

$squares = array_map(function($n) { return $n * $n; }, $numbers);

Но стрелочные функции — это современный стандарт. Если твой проект на PHP 8+, используй их всегда.

А что, если нужно обработать несколько массивов одновременно? array_map умеет принимать несколько массивов. Например, сложим элементы двух массивов поэлементно:

$a = [1, 2, 3];
$b = [10, 20, 30];
$sum = array_map(fn($x, $y) => $x + $y, $a, $b);
// $sum = [11, 22, 33]

Важно: если массивы разной длины, PHP дополнит недостающие элементы значениями null. Будь внимателен.

array_filter: оставляем только то, что нужно

array_filter — это твой личный фильтр для данных. Ты задаёшь условие, и функция возвращает только те элементы, которые ему соответствуют.

Пример: выберем только чётные числа.

$numbers = [1, 2, 3, 4, 5, 6];
$even = array_filter($numbers, fn($n) => $n % 2 === 0);
// $even = [2, 4, 6]

По умолчанию array_filter без callback удаляет все элементы, которые в логическом контексте равны false: пустые строки, null, 0, false. Это удобно для очистки массива от «мусора».

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

$evenIndexed = array_values($even);
// теперь ключи: 0, 1, 2
ФункцияЧто делаетКогда использовать
array_mapПреобразует каждый элементНужно изменить данные, но сохранить структуру
array_filterОставляет элементы по условиюНужно отсеять лишнее
array_reduceСводит массив к одному значениюНужно посчитать сумму, произведение или объединить строки

array_reduce: сворачиваем горы в песчинку

array_reduce — это функция, которая «сворачивает» массив в одно значение. Представь, что у тебя есть куча деталей, и ты собираешь из них один механизм. Именно это и делает array_reduce.

Классический пример — сумма чисел:

$numbers = [1, 2, 3, 4, 5];
$sum = array_reduce($numbers, fn($carry, $item) => $carry + $item, 0);
// $sum = 15

Параметр $carry — это аккумулятор, который передаётся от одной итерации к другой. Начальное значение — 0. Если не указать начальное значение, первым $carry будет первый элемент массива, но это может привести к ошибкам на пустом массиве. Всегда указывай начальное значение.

Более сложный пример: превратим массив строк в ассоциативный массив, где ключ — первая буква.

$words = ['apple', 'banana', 'apricot', 'cherry'];
$grouped = array_reduce($words, function($carry, $word) {
    $firstLetter = $word[0];
    $carry[$firstLetter][] = $word;
    return $carry;
}, []);
// ['a' => ['apple', 'apricot'], 'b' => ['banana'], 'c' => ['cherry']]

Это мощный инструмент для группировки данных.

Спред-оператор и деструктуризация: новый взгляд на массивы

Начиная с PHP 7.4, в массивах можно использовать спред-оператор (...). Он позволяет распаковать массив в другой массив или в аргументы функции.

Пример: слияние массивов.

$first = [1, 2, 3];
$second = [4, 5, 6];
$merged = [...$first, ...$second];
// $merged = [1, 2, 3, 4, 5, 6]

Раньше для этого использовали array_merge. Спред-оператор работает быстрее и читается легче. Но есть нюанс: он работает только с индексированными массивами. Для ассоциативных массивов лучше использовать array_merge или оператор +.

Деструктуризация — это когда ты извлекаешь элементы массива в переменные одной строкой.

$data = ['John', 25, 'London'];
[$name, $age, $city] = $data;
echo $name; // John

Можно пропускать элементы, используя пустые запятые:

[$name, , $city] = $data;
// $age не определена

Совет: используй деструктуризацию в циклах foreach для работы с массивами пар.

$pairs = [['a', 1], ['b', 2]];
foreach ($pairs as [$letter, $number]) {
    echo "$letter: $number\n";
}

Генераторы: когда массив слишком велик

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

Пример: генератор чисел Фибоначчи.

function fibonacci($limit) {
    $a = 0;
    $b = 1;
    for ($i = 0; $i < $limit; $i++) {
        yield $a;
        [$a, $b] = [$b, $a + $b];
    }
}

foreach (fibonacci(10) as $number) {
    echo $number . ' ';
}
// 0 1 1 2 3 5 8 13 21 34

Генераторы — это не совсем массивы, но они работают с ними в одном контексте. Ты можешь передать генератор в array_map или iterator_to_array, если нужно получить массив.

Лайфхак: если ты работаешь с API, которое возвращает пагинированные данные, используй генератор для итерации по страницам. Это сэкономит память.

Правило: Если данные могут быть большими (больше 1000 элементов), подумай, нужен ли тебе массив целиком. Возможно, генератор решит проблему производительности.

Что в итоге

Продвинутые техники работы с массивами — это не просто модные фишки. Они делают код короче, быстрее и понятнее. Используй array_map для преобразований, array_filter для фильтрации, array_reduce для сводных данных, спред-оператор для слияния, а генераторы для экономии памяти. И главное — не бойся экспериментировать. PHP даёт тебе мощные инструменты, так что пользуйся ими.

Студия WNDER