Массивы в языке PHP
Основы работы с массивами в PHP
Массивы в PHP представляют собой упорядоченные структуры данных, которые могут содержать элементы различных типов. Каждый элемент имеет ключ (индекс), который может быть числом или строкой. PHP поддерживает как числовые (индексированные) массивы, так и ассоциативные (с именованными ключами), а также многомерные массивы.
Как создать массив в PHP?
Основной способ - использование функции array() или короткого синтаксиса []:
$arr1 = array(10, 20, 30);
$arr2 = [10, 20, 30];Php массивы (массивы в php)
Оба варианта создают массив с элементами 10, 20, 30 и автоматическими числовыми ключами 0, 1, 2. Результат одинаков.
Важно: короткий синтаксис появился в PHP 5.4 и теперь считается стандартом.
Какие существуют альтернативные способы создания массивов?
Можно создать пустой массив и добавлять элементы позже:
$empty = [];
$empty[] = 'первый';
$empty[] = 'второй';Функция range() генерирует последовательность чисел:
$numbers = range(1, 5);
// [1, 2, 3, 4, 5]Ассоциативный массив можно создать, явно указав ключи:
$user = ['name' => 'Иван', 'age' => 30];Также существует функция array_fill() для заполнения массива одинаковыми значениями:
$filled = array_fill(0, 3, 'default');
// [0 => 'default', 1 => 'default', 2 => 'default']Типичные ошибки при создании
- Попытка использовать короткий синтаксис в PHP версии ниже 5.4 - приводит к синтаксической ошибке.
- Путаница с ключами: если не указать ключ, PHP присваивает следующий числовой индекс, начиная с 0. Но если предыдущий элемент имел строковый ключ, это не влияет на автоматический индекс.
- Использование
array()с одним параметромarray(1)создаёт массив с одним элементом, а не массив из 1.
Как получить доступ к элементам массива?
Доступ к элементу осуществляется по ключу в квадратных скобках:
$arr = ['a', 'b', 'c'];
echo $arr[0]; // 'a'$assoc = ['name' => 'Анна', 'city' => 'Москва'];
echo $assoc['name']; // 'Анна'Если ключ не существует, PHP генерирует предупреждение Notice: Undefined index. Для безопасной проверки используют isset() или array_key_exists().
Как проверить существование ключа в массиве?
Функция array_key_exists() проверяет, есть ли ключ, даже если значение null:
$data = ['key' => null];
var_dump(isset($data['key'])); // false
var_dump(array_key_exists('key', $data)); // trueИспользуйте isset() когда нужно проверить, что ключ существует и его значение не равно null.
Какие операции добавления и удаления элементов доступны?
Добавление в конец массива:
$arr = [1, 2];
$arr[] = 3; // [1, 2, 3]
array_push($arr, 4); // [1,2,3,4]Удаление последнего элемента - array_pop():
$last = array_pop($arr); // $last = 4, $arr = [1,2,3]Удаление первого элемента - array_shift():
$first = array_shift($arr); // $first = 1, $arr = [2,3]Добавление в начало - array_unshift():
array_unshift($arr, 0); // $arr = [0,2,3]Как удалить элемент по ключу?
Оператор unset() удаляет элемент по ключу, но не переиндексирует массив:
$arr = [10, 20, 30];
unset($arr[1]); // $arr = [0=>10, 2=>30]Для переиндексации после удаления используйте array_values():
$arr = array_values($arr); // [0=>10, 1=>30]Ошибки при добавлении/удалении
- После
unset()остаются дыры в индексах, что может привести к неожиданному поведению при обходе через for. - Использование
array_push()с одним элементом неэффективно по сравнению с$arr[] =. - При удалении из ассоциативного массива ключи сохраняются.
Как обойти массив в цикле?
Основной способ - foreach:
$colors = ['red', 'green', 'blue'];
foreach ($colors as $color) {
echo $color;
}Для ассоциативных массивов:
$person = ['name' => 'Петр', 'age' => 25];
foreach ($person as $key => $value) {
echo "$key: $value\n";
}Также можно использовать for с числовым индексом, если массив непрерывно индексирован:
for ($i = 0; $i < count($arr); $i++) {
echo $arr[$i];
}Какие ещё существуют способы обхода?
Функция array_walk() применяет callback к каждому элементу:
array_walk($colors, function(&$value) {
$value = strtoupper($value);
});array_map() возвращает новый массив с преобразованными значениями:
$upper = array_map('strtoupper', $colors);array_filter() фильтрует массив по callback:
$numbers = [1,2,3,4,5];
$even = array_filter($numbers, function($n) {
return $n % 2 == 0;
}); // [1=>2, 3=>4] (ключи сохраняются)Типичные проблемы обхода
- Изменение массива внутри
foreachпо значению не влияет на исходный массив. Для изменения нужно передавать по ссылке:foreach ($arr as &$value). - Использование
forпосле удаления элементов (unset) приводит к ошибкам из-за дырок в индексах. - При
foreachпо ссылке после цикла переменная ссылка остаётся, что может вызвать побочные эффекты - рекомендуетсяunset($value)после цикла.
Как отсортировать массив?
PHP предоставляет множество функций сортировки:
sort()- сортировка по значениям, ключи переиндексируются.asort()- сортировка по значениям, ключи сохраняются.ksort()- сортировка по ключам.rsort(),arsort(),krsort()- обратные сортировки.
$fruits = ['banana', 'apple', 'cherry'];
sort($fruits);
print_r($fruits); // [0=>'apple',1=>'banana',2=>'cherry']$ages = ['Иван' => 30, 'Анна' => 25];
asort($ages); // ключи сохраняются: ['Анна'=>25, 'Иван'=>30]Для пользовательских критериев используется usort():
$numbers = [3, 1, 4, 1, 5];
usort($numbers, function($a, $b) {
return $b - $a; // по убыванию
});Как объединить или сравнить массивы?
Объединение - array_merge():
$a = [1, 2];
$b = [3, 4];
$c = array_merge($a, $b); // [1,2,3,4]Для ассоциативных массивов при совпадении ключей более поздние перезаписывают более ранние.
Разность - array_diff():
$a = [1, 2, 3];
$b = [2, 3, 4];
$diff = array_diff($a, $b); // [0=>1]Пересечение - array_intersect():
$intersect = array_intersect($a, $b); // [1=>2, 2=>3]Ошибки сортировки и объединения
array_merge()на числовых массивах переиндексирует ключи, что может нарушить ожидаемый порядок.- После
sort()ассоциативный массив теряет ключи, поэтому используйтеasort().
Как работать с многомерными массивами?
Многомерный массив - это массив, содержащий другие массивы в качестве элементов. Например, матрица 3x3:
$matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
echo $matrix[1][2]; // 6Ассоциативный многомерный массив:
$students = [
['name' => 'Иван', 'grades' => [5,4,3]],
['name' => 'Мария', 'grades' => [4,5,5]]
];
echo $students[0]['grades'][1]; // 4Как преобразовать многомерный массив в одномерный?
Функция array_column() извлекает столбец из многомерного массива:
$names = array_column($students, 'name'); // ['Иван', 'Мария']Для рекурсивного сглаживания используется array_walk_recursive или пользовательская рекурсия.
Проблемы с многомерными массивами
- Обращение к несуществующему вложенному ключу вызывает предупреждение.
- При копировании многомерного массива изменения во вложенных массивах могут отражаться в обоих, если не использовать глубокое копирование.
Расширенные примеры работы с массивами
Как использовать array_reduce для свёртки массива?
array_reduce() преобразует массив в одно значение с помощью callback:
$numbers = [1, 2, 3, 4];
$sum = array_reduce($numbers, function($carry, $item) {
return $carry + $item;
}, 0); // 10Результат: 10
Можно также собрать строку из элементов:
$words = ['Hello', 'world'];
$sentence = array_reduce($words, function($carry, $word) {
return $carry . ' ' . $word;
}, ''); // ' Hello world'Как разбить массив на чанки (группы) определённого размера?
array_chunk() делит массив на подмассивы заданной длины:
$data = [1,2,3,4,5,6,7];
$chunks = array_chunk($data, 3);
print_r($chunks);Array
(
[0] => Array ([0] => 1 [1] => 2 [2] => 3)
[1] => Array ([0] => 4 [1] => 5 [2] => 6)
[2] => Array ([0] => 7)
)Для ассоциативных массивов можно сохранить ключи, передав true вторым параметром.
Как объединить два массива в один, используя один как ключи, а другой как значения?
array_combine() создаёт ассоциативный массив из массивов ключей и значений:
$keys = ['a', 'b', 'c'];
$values = [1, 2, 3];
$combined = array_combine($keys, $values);
print_r($combined);Array
(
[a] => 1
[b] => 2
[c] => 3
)Важно: оба массива должны иметь одинаковое количество элементов, иначе возникнет предупреждение.
Как найти разность массивов с учётом ключей?
array_diff_assoc() сравнивает и значения, и ключи:
$a = ['x' => 1, 'y' => 2, 'z' => 3];
$b = ['x' => 1, 'y' => 22, 'w' => 3];
$diff = array_diff_assoc($a, $b);
print_r($diff);Array
(
[y] => 2
[z] => 3
)Элемент 'z' => 3 не совпадает по ключу 'z' против 'w', поэтому включается в разность.
Как применить callback ко всем элементам массива и вернуть новый массив?
array_map() возвращает массив той же длины:
$lengths = ['apple', 'banana', 'cherry'];
$uppers = array_map('strtoupper', $lengths);
print_r($uppers);Array
(
[0] => APPLE
[1] => BANANA
[2] => CHERRY
)Можно передать несколько массивов - callback получит соответствующие элементы каждого:
$a = [1,2,3];
$b = [10,20,30];
$sums = array_map(function($x, $y) { return $x + $y; }, $a, $b);
print_r($sums); // [11,22,33]Как отфильтровать массив с сохранением ключей?
array_filter() по умолчанию сохраняет ключи. Можно указать ключи для фильтрации или передать ARRAY_FILTER_USE_KEY:
$arr = ['a' => 1, 'b' => 0, 'c' => 3];
$filtered = array_filter($arr); // удаляет элементы с falsy значениями (0)
print_r($filtered); // ['a'=>1, 'c'=>3]$keys = ['a', 'b', 'c', 'd'];
$filteredByKey = array_filter($keys, function($key) {
return $key !== 'b';
}, ARRAY_FILTER_USE_KEY); // только ключи 'a','c','d'Как получить все ключи или все значения массива?
array_keys() и array_values():
$colors = ['red' => '#FF0000', 'green' => '#00FF00'];
$keys = array_keys($colors); // ['red', 'green']
$values = array_values($colors); // ['#FF0000', '#00FF00']array_keys() может также искать ключи, соответствующие определённому значению: array_keys($colors, '#FF0000') вернёт ['red'].
Как проверить, содержится ли элемент в массиве?
in_array() проверяет наличие значения (по умолчанию строгое сравнение отключено; для строгой проверки передайте true третьим параметром):
$haystack = [1, '2', 3];
var_dump(in_array(2, $haystack)); // true (нестрогое сравнение '2' == 2)
var_dump(in_array(2, $haystack, true)); // false (строгое: тип значения 2 не совпадает с '2')Аналог для ключей - array_key_exists().
Как получить случайный элемент из массива?
array_rand() возвращает случайный ключ (или массив ключей, если указать количество):
$deck = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
$randomKey = array_rand($deck);
echo $deck[$randomKey];Можно получить несколько случайных элементов: $keys = array_rand($deck, 3); - ключи в случайном порядке.
Как удалить повторяющиеся значения из массива?
array_unique() удаляет дубликаты, оставляя первое вхождение:
$duplicates = [1, 2, 2, 3, 3, 3];
$unique = array_unique($duplicates);
print_r($unique); // [0=>1,1=>2,3=>3]Ключи сохраняются. Для переиндексации используйте array_values().
Как изменить порядок элементов на обратный?
array_reverse() возвращает массив с обратным порядком элементов:
$forward = [1,2,3];
$backward = array_reverse($forward);
print_r($backward); // [0=>3,1=>2,2=>1]По умолчанию ключи сохраняются. Для числовых массивов можно передать true для сброса ключей: array_reverse($forward, true) - ключи тоже будут переставлены.
Как применить callback к каждому элементу без создания нового массива?
array_walk() изменяет исходный массив, если передавать элемент по ссылке:
$arr = [1, 2, 3];
array_walk($arr, function(&$value, $key) {
$value = $value * 2;
});
print_r($arr); // [2,4,6]Для рекурсивного обхода многомерных массивов используется array_walk_recursive().
Как преобразовать массив в строку с разделителем?
Функция implode() (синоним join()) соединяет элементы массива:
$parts = ['PHP', 'MySQL', 'JavaScript'];
$commaSeparated = implode(', ', $parts);
echo $commaSeparated; // PHP, MySQL, JavaScriptЕсли массив ассоциативный, значения соединяются, ключи игнорируются.
Часто встречающиеся ошибки в расширенных примерах
- При использовании
array_map()с несколькими массивами разные длины приводят к заполнению отсутствующих элементовnull. array_unique()не рекурсивен; для многомерных массивов требуется пользовательская логика.- Изменение массива внутри
array_walk()с передачей по ссылке может привести к неожиданным результатам, если callback не ожидает ссылку. - При использовании
array_combine()дублирующиеся ключи из массива$keysперезаписываются последним значением. - В
array_reduce()начальное значение$carryможет быть любого типа, но callback должен корректно обрабатывать первый вызов.