PHP数组与集合方法——详细指南
Что это такое и зачем? (аналогия из реальной жизни)
Представь, что ты — библиотекарь. У тебя есть огромный стеллаж, на котором стоят книги. Каждая книга — это отдельный элемент данных (число, строка, другой массив). Сам стеллаж — это и есть массив (array).
Без методов тебе пришлось бы каждый раз вручную перебирать все книги, чтобы найти нужную, посчитать их количество или отсортировать по алфавиту. Это долго и утомительно. Методы массивов — это как волшебные кнопки на пульте управления библиотекой. Нажал одну — и все книги автоматически отсортировались. Нажал другую — нашёл все книги определённого автора. Третья кнопка — удалила все старые книги.
В программировании массивы встречаются постоянно: список пользователей на сайте, корзина товаров в интернет-магазине, результаты поиска, настройки игры. Уметь быстро и правильно обрабатывать массивы — это базовый навык, без которого невозможно написать ни одну серьёзную программу.
💡 Важно: Методы не изменяют оригинальный массив (если не сказано обратное). Они возвращают новый результат. Это как сделать ксерокопию страницы и работать с ней, а оригинал оставить нетронутым.
Теория: как это работает изнутри
В PHP массив — это упорядоченная структура данных, которая хранит пары «ключ => значение». Ключом может быть число (индекс) или строка. Значением — что угодно: число, строка, другой массив, объект.
Когда ты вызываешь метод массива, PHP внутри делает следующее:
- Берёт твой массив (оригинал).
- Создаёт внутреннюю копию (или работает с оригиналом, если метод изменяющий).
- Применяет к каждому элементу заданную логику (сравнение, фильтрацию, преобразование).
- Возвращает результат: новый массив, одно значение (число, строку) или
true/false.
Большинство методов используют циклы внутри себя. Например, array_map внутри делает то же самое, что и foreach, но короче и понятнее.
Важно понимать разницу между:
- Индексированным массивом — ключи — числа (0, 1, 2...). Как список.
- Ассоциативным массивом — ключи — строки. Как словарь.
- Многомерным массивом — массив внутри массива. Как таблица или дерево.
Методы работают со всеми типами, но некоторые (например, array_keys) особенно полезны для ассоциативных массивов.
Синтаксис в PHP: все формы и варианты
В PHP методы массивов делятся на две большие группы:
- Функции — вызываются как
имя_функции(массив, параметры). Это исторически сложилось. Пример:array_map(...). - Методы объектов — если ты используешь коллекции (например, из Laravel или Symfony). Вызываются через стрелку:
$collection->filter(...).
В этой статье мы сосредоточимся на функциях, так как это основа PHP. Но в конце покажем пример с коллекциями.
Основные функции массивов (шпаргалка)
| Функция | Что делает | Возвращает |
|---|---|---|
array_map |
Применяет функцию к каждому элементу | Новый массив |
array_filter |
Фильтрует элементы по условию | Новый массив |
array_reduce |
Сворачивает массив в одно значение | Одно значение (строка, число) |
array_merge |
Сливает два или более массивов | Новый массив |
array_keys |
Возвращает все ключи массива | Новый массив |
array_values |
Возвращает все значения массива | Новый массив |
in_array |
Проверяет, есть ли значение в массиве | true/false |
array_search |
Ищет значение и возвращает его ключ | Ключ или false |
sort |
Сортирует массив по значениям | true (изменяет оригинал) |
rsort |
Сортирует в обратном порядке | true (изменяет оригинал) |
asort |
Сортирует, сохраняя ключи | true (изменяет оригинал) |
ksort |
Сортирует по ключам | true (изменяет оригинал) |
count |
Считает количество элементов | Число |
array_unique |
Удаляет дубликаты | Новый массив |
array_reverse |
Переворачивает массив задом наперёд | Новый массив |
array_slice |
Вырезает часть массива | Новый массив |
array_splice |
Удаляет или заменяет часть массива | Массив удалённых элементов |
array_rand |
Выбирает случайный ключ | Ключ или массив ключей |
array_shift |
Удаляет первый элемент | Удалённый элемент |
array_pop |
Удаляет последний элемент | Удалённый элемент |
array_push |
Добавляет элемент в конец | Новое количество элементов |
array_unshift |
Добавляет элемент в начало | Новое количество элементов |
⚠️ Запомни: Функцииsort,rsort,asort,ksort,array_shift,array_pop,array_push,array_unshift,array_splice— изменяют оригинальный массив. Будь осторожен!
Примеры кода — от простого к сложному
Пример 1: array_map — увеличиваем каждое число в 2 раза
<?php
// У нас есть массив с числами
$numbers = [1, 2, 3, 4, 5];
// Создаём функцию, которая будет применяться к каждому элементу
// Она принимает одно значение и возвращает новое
$multiplyByTwo = function($n) {
return $n * 2;
};
// Применяем array_map: первый аргумент — наша функция, второй — массив
$doubled = array_map($multiplyByTwo, $numbers);
// Выводим результат
print_r($doubled);
// Результат: Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
// Можно записать короче, используя анонимную функцию прямо внутри вызова:
$doubled_short = array_map(function($n) { return $n * 2; }, $numbers);
?>
Объяснение: array_map проходит по каждому элементу массива $numbers, передаёт его в функцию $multiplyByTwo, которая умножает число на 2, и собирает результаты в новый массив $doubled. Исходный массив остаётся без изменений.
Пример 2: array_filter — оставляем только чётные числа
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Функция-фильтр: возвращает true, если число чётное
$isEven = function($n) {
return $n % 2 === 0;
};
// array_filter применяет функцию к каждому элементу
// Если функция вернула true — элемент остаётся, если false — удаляется
$evenNumbers = array_filter($numbers, $isEven);
// Выводим результат
print_r($evenNumbers);
// Результат: Array ( [1] => 2 [3] => 4 [5] => 6 [7] => 8 [9] => 10 )
// Обрати внимание: ключи сохранились! (1, 3, 5, 7, 9)
// Если хочешь сбросить ключи, используй array_values:
$evenNumbersClean = array_values($evenNumbers);
print_r($evenNumbersClean);
// Результат: Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
?>
Объяснение: array_filter проверяет каждый элемент на соответствие условию. Если условие истинно — элемент попадает в новый массив. Важно: ключи сохраняются, поэтому после фильтрации массив может иметь «дырки» в нумерации.
Пример 3: array_reduce — считаем сумму всех чисел
<?php
$numbers = [10, 20, 30, 40, 50];
// Функция для свёртки: принимает текущий результат (carry) и текущий элемент
$sum = function($carry, $item) {
// Прибавляем текущий элемент к накопленному результату
return $carry + $item;
};
// Третий аргумент — начальное значение (0)
$total = array_reduce($numbers, $sum, 0);
echo "Сумма: " . $total; // Выведет: Сумма: 150
// Можно посчитать произведение, если начать с 1:
$product = array_reduce($numbers, function($carry, $item) {
return $carry * $item;
}, 1);
echo "Произведение: " . $product; // Выведет: Произведение: 12000000
?>
Объяснение: array_reduce — это как конвейер. На каждом шаге к текущему результату ($carry) применяется операция с текущим элементом ($item). Начальное значение задаётся третьим аргументом. Идеально для подсчёта суммы, среднего, произведения, конкатенации строк.
Пример 4: array_merge — объединяем списки учеников
<?php
// Два массива с именами учеников
$classA = ["Аня", "Борис", "Вика"];
$classB = ["Глеб", "Даша", "Егор"];
// Объединяем их в один общий список
$allStudents = array_merge($classA, $classB);
print_r($allStudents);
// Результат: Array ( [0] => Аня [1] => Борис [2] => Вика [3] => Глеб [4] => Даша [5] => Егор )
// Если ключи строковые и совпадают, array_merge перезапишет значения:
$person1 = ["name" => "Иван", "age" => 25];
$person2 = ["name" => "Петр", "city" => "Москва"];
$merged = array_merge($person1, $person2);
print_r($merged);
// Результат: Array ( [name] => Петр [age] => 25 [city] => Москва )
// Ключ 'name' был перезаписан вторым массивом!
?>
Объяснение: array_merge соединяет два или более массивов в один. Для числовых ключей — просто добавляет в конец. Для строковых — перезаписывает значения, если ключи совпадают. Будь внимателен с этим!
Пример 5: array_keys и array_values — работаем с ассоциативным массивом
<?php
// Ассоциативный массив: товары и их цены
$products = [
"яблоко" => 50,
"банан" => 30,
"апельсин" => 70,
"киви" => 40
];
// Получаем все названия товаров (ключи)
$names = array_keys($products);
print_r($names);
// Результат: Array ( [0] => яблоко [1] => банан [2] => апельсин [3] => киви )
// Получаем все цены (значения)
$prices = array_values($products);
print_r($prices);
// Результат: Array ( [0] => 50 [1] => 30 [2] => 70 [3] => 40 )
// Проверяем, есть ли товар "банан" в массиве
if (in_array("банан", $names)) {
echo "Банан есть в списке!";
}
// Ищем цену товара "апельсин"
$key = array_search("апельсин", $names);
if ($key !== false) {
echo "Цена апельсина: " . $products[$names[$key]];
}
?>
Объяснение: array_keys извлекает все ключи, array_values — все значения. in_array проверяет наличие значения (возвращает true/false). array_search ищет значение и возвращает его ключ (или false, если не найдено).
Пример 6: Сортировка — от А до Я и от дорогого к дешёвому
<?php
$fruits = ["банан", "яблоко", "апельсин", "киви"];
// Сортировка по алфавиту (изменяет оригинал!)
sort($fruits);
print_r($fruits);
// Результат: Array ( [0] => апельсин [1] => банан [2] => киви [3] => яблоко )
// Обратная сортировка
rsort($fruits);
print_r($fruits);
// Результат: Array ( [0] => яблоко [1] => киви [2] => банан [3] => апельсин )
// Ассоциативный массив: товар => цена
$prices = [
"яблоко" => 50,
"банан" => 30,
"апельсин" => 70,
"киви" => 40
];
// Сортировка по цене (по значениям), сохраняя ключи
asort($prices);
print_r($prices);
// Результат: Array ( [банан] => 30 [киви] => 40 [яблоко] => 50 [апельсин] => 70 )
// Сортировка по названию (по ключам)
ksort($prices);
print_r($prices);
// Результат: Array ( [апельсин] => 70 [банан] => 30 [киви] => 40 [яблоко] => 50 )
?>
Объяснение: sort и rsort сортируют по значениям, но сбрасывают ключи. asort сортирует по значениям, сохраняя ключи (идеально для ассоциативных массивов). ksort сортирует по ключам. Все эти функции изменяют оригинальный массив.
Пример 7: array_unique и array_reverse — убираем дубли и переворачиваем
<?php
// Массив с повторяющимися элементами
$colors = ["красный", "синий", "зеленый", "красный", "желтый", "синий"];
// Удаляем дубликаты
$uniqueColors = array_unique($colors);
print_r($uniqueColors);
// Результат: Array ( [0] => красный [1] => синий [2] => зеленый [4] => желтый )
// Ключи сохранились, но есть пропуски
// Переворачиваем массив задом наперёд
$reversed = array_reverse($uniqueColors);
print_r($reversed);
// Результат: Array ( [0] => желтый [1] => зеленый [2] => синий [3] => красный )
// Ключи сброшены (0, 1, 2, 3)
// Если хочешь сохранить ключи при перевороте, передай true вторым аргументом:
$reversedWithKeys = array_reverse($uniqueColors, true);
print_r($reversedWithKeys);
// Результат: Array ( [4] => желтый [2] => зеленый [1] => синий [0] => красный )
?>
Объяснение: array_unique удаляет повторяющиеся значения. array_reverse переворачивает порядок элементов. Второй аргумент true заставляет сохранить ключи.
Пример 8: array_slice и array_splice — вырезаем и заменяем
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// array_slice — берём часть массива (не изменяет оригинал)
// Первые 3 элемента
$firstThree = array_slice($numbers, 0, 3);
print_r($firstThree);
// Результат: Array ( [0] => 1 [1] => 2 [2] => 3 )
// Элементы с 4-го по 7-й (индексы 3, 4, 5, 6)
$middle = array_slice($numbers, 3, 4);
print_r($middle);
// Результат: Array ( [0] => 4 [1] => 5 [2] => 6 [3] => 7 )
// array_splice — удаляет часть массива (изменяет оригинал!)
// Удаляем 3 элемента, начиная с индекса 2
$removed = array_splice($numbers, 2, 3);
print_r($removed); // Удалённые элементы: Array ( [0] => 3 [1] => 4 [2] => 5 )
print_r($numbers); // Оригинал изменился: Array ( [0] => 1 [1] => 2 [2] => 6 [3] => 7 [4] => 8 [5] => 9 [6] => 10 )
// Можно заменить удалённые элементы новыми:
$numbers2 = [1, 2, 3, 4, 5];
array_splice($numbers2, 1, 2, ["a", "b", "c"]);
print_r($numbers2);
// Результат: Array ( [0] => 1 [1] => a [2] => b [3] => c [4] => 4 [5] => 5 )
?>
Объяснение: array_slice — безопасная функция для извлечения части массива. array_splice — мощная, но опасная: она изменяет оригинал. Может удалять, заменять и добавлять элементы одновременно.
Пример 9: array_rand — случайный выбор
<?php
$students = ["Аня", "Борис", "Вика", "Глеб", "Даша"];
// Выбираем одного случайного ученика
$randomKey = array_rand($students);
echo "Случайный ученик: " . $students[$randomKey];
// Выбираем 3 случайных учеников (возвращает массив ключей)
$randomKeys = array_rand($students, 3);
echo "Случайные ученики: ";
foreach ($randomKeys as $key) {
echo $students[$key] . " ";
}
// Результат: например, "Вика Глеб Аня"
?>
Объяснение: array_rand возвращает один или несколько случайных ключей из массива. Удобно для розыгрышей, случайного контента, тестовых заданий.
Пример 10: Работа с многомерным массивом — список студентов и их оценки
<?php
// Многомерный массив: каждый студент — это ассоциативный массив
$students = [
["name" => "Аня", "grade" => 85],
["name" => "Борис", "grade" => 92],
["name" => "Вика", "grade" => 78],
["name" => "Глеб", "grade" => 95],
["name" => "Даша", "grade" => 88]
];
// Используем array_map, чтобы извлечь только имена
$names = array_map(function($student) {
return $student["name"];
}, $students);
print_r($names);
// Результат: Array ( [0] => Аня [1] => Борис [2] => Вика [3] => Глеб [4] => Даша )
// Фильтруем: оставляем только тех, у кого оценка выше 85
$excellent = array_filter($students, function($student) {
return $student["grade"] > 85;
});
print_r($excellent);
// Результат: Array ( [1] => Array ( [name] => Борис [grade] => 92 ) [3] => Array ( [name] => Глеб [grade] => 95 ) [4] => Array ( [name] => Даша [grade] => 88 ) )
// Сортируем по оценкам (по убыванию)
usort($students, function($a, $b) {
return $b["grade"] - $a["grade"];
});
print_r($students);
// Результат: Глеб (95), Борис (92), Даша (88), Аня (85), Вика (78)
?>
Объяснение: Многомерные массивы — это массивы, элементами которых являются другие массивы. Для работы с ними используются те же функции, но с дополнительной логикой внутри callback-функций. usort — это пользовательская сортировка, где ты сам задаёшь правило сравнения.
Сравнение с Python: чем похоже и чем отличается
Если ты уже знаком с Python, тебе будет проще. Но есть важные различия.
| Действие | PHP | Python |
|---|---|---|
| Создание списка | $arr = [1, 2, 3]; |
arr = [1, 2, 3] |
| Применить функцию ко всем элементам | array_map('fn', $arr) |
map(fn, arr) или [fn(x) for x in arr] |
| Фильтрация | array_filter($arr, 'fn') |
filter(fn, arr) или [x for x in arr if условие] |
| Свёртка (сумма) | array_reduce($arr, 'fn', 0) |
functools.reduce(fn, arr, 0) или sum(arr) |
| Сортировка | sort($arr) (изменяет оригинал) |
arr.sort() (изменяет оригинал) |
| Сортировка с возвратом нового | $sorted = $arr; sort($sorted); |
sorted(arr) |
| Длина массива | count($arr) |
len(arr) |
| Проверка наличия | in_array($val, $arr) |
val in arr |
| Объединение | array_merge($a, $b) |
a + b или a.extend(b) |
| Уникальные значения | array_unique($arr) |
set(arr) |
| Случайный элемент | $arr[array_rand($arr)] |
random.choice(arr) |
Главные отличия:
- Синтаксис: В PHP функции — это отдельные функции, а не методы объекта. В Python методы вызываются через точку (
arr.sort()). - Callback-функции: В PHP ты передаёшь имя функции или анонимную функцию. В Python — lambda-выражения или обычные функции.
- Изменение оригинала: В PHP некоторые функции изменяют оригинал (sort, array_pop), некоторые нет. В Python методы списков обычно изменяют оригинал, а встроенные функции (sorted, reversed) возвращают новые.
- Типизация: PHP — динамическая типизация, но массивы могут быть только массивами. Python — тоже динамическая, но списки, кортежи, множества и словари — разные типы.
💡 Совет: Если ты переходишь с Python на PHP, запомни: в PHP почти всё делается через функции, а не через методы. Привыкай к синтаксису array_....
Типичные ошибки и подводные камни
-
Забыл, что функция изменяет оригинал.
Пример:
sort($arr);— после этого$arrизменён. Если ты хотел сохранить оригинал, сделай копию:$sorted = $arr; sort($sorted);. -
Путаница между array_map и array_filter.
array_mapвсегда возвращает массив той же длины, но с преобразованными значениями.array_filterможет вернуть массив меньшей длины (если некоторые элементы не прошли фильтр). -
Использование array_merge с числовыми ключами.
Если ключи числовые,
array_mergeпросто добавляет элементы в конец. Но если ключи строковые и совпадают — значения перезаписываются. Это часто приводит к неожиданным багам. -
Забыл про array_values после array_filter.
После фильтрации ключи сохраняются. Если ты ожидаешь массив с ключами 0, 1, 2..., используй
array_values(). -
Использование in_array для поиска в многомерном массиве.
in_arrayработает только с одномерными массивами. Для многомерных нужно писать рекурсивную функцию или использоватьarray_column. -
Сравнение с false в array_search.
array_searchможет вернуть 0 (нулевой ключ). Если ты проверишьif ($key), то 0 будет интерпретирован как false. Всегда используй строгое сравнение: <