W3docs

Многомерные массивы в PHP

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

Многомерный массив в PHP — это массив, элементы которого сами являются массивами. Обычный (индексированный или ассоциативный) массив сопоставляет каждый ключ с одним значением, тогда как многомерный массив сопоставляет каждый ключ с целым вложенным массивом — что позволяет моделировать данные в виде таблиц, сеток, деревьев и сгруппированных записей.

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

Что такое многомерный массив?

Массив становится многомерным, когда одно из его значений само является массивом. Размерность (или глубина) — это количество операций индексирования, необходимых для достижения скалярного значения:

  • $a[0] достигает значения → одномерный
  • $a[0][1] достигает значения → двумерный
  • $a[0][1][2] достигает значения → трёхмерный, и так далее.

Двумерный массив часто представляют как таблицу: внешний массив содержит строки, а каждый внутренний массив содержит столбцы этой строки. Эта мысленная модель полезна, но помните, что массивы PHP — это упорядоченные отображения, а не жёсткие сетки — строки могут иметь разную длину, а ключи могут быть строками вместо 0, 1, 2. Ограничения на глубину нет, однако сильно вложенные данные обычно свидетельствуют о том, что лучше использовать объекты или базу данных.

Создание многомерного массива

Наиболее распространённый способ — вкладывать литералы массивов. Каждый внутренний массив является одним элементом внешнего массива.

Двумерный массив строк (сетка)

$grid = [
    ["value1", "value2", "value3"],
    ["value4", "value5", "value6"],
    ["value7", "value8", "value9"],
];

В реальном коде внутренние массивы обычно ассоциативные, поэтому каждая строка читается как запись:

Список записей

$employees = [
    ["name" => "Ann",  "title" => "Engineer", "salary" => 65000],
    ["name" => "Bob",  "title" => "Designer", "salary" => 58000],
    ["name" => "Cara", "title" => "Manager",  "salary" => 72000],
];

Можно также строить массив поэтапно — это удобно, когда данные поступают из цикла или запроса к базе данных:

$matrix = [];
$matrix[0][0] = 1;
$matrix[0][1] = 2;
$matrix[1][0] = 3;
$matrix[1][1] = 4;
// $matrix is now [[1, 2], [3, 4]]

Доступ к элементам

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

echo $grid[1][2];          // "value6" — row 1, column 2
echo $employees[2]["name"]; // "Cara"

PHP использует нулевую индексацию, поэтому вторая строка — это [1], а третий столбец — [2]. Обращение к несуществующему ключу вызывает предупреждение и возвращает null; используйте isset() или оператор null-объединения для безопасного доступа:

$salary = $employees[5]["salary"] ?? 0; // no warning if the row is missing

Перебор многомерного массива

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

$employees = [
    ["name" => "Ann",  "salary" => 65000],
    ["name" => "Bob",  "salary" => 58000],
];

foreach ($employees as $row) {
    foreach ($row as $key => $value) {
        echo "$key: $value\n";
    }
    echo "---\n";
}

Для табличных записей зачастую удобнее сразу деструктурировать внутренние ключи:

foreach ($employees as $emp) {
    echo "{$emp['name']} earns {$emp['salary']}\n";
}
// Ann earns 65000
// Bob earns 58000

Изменение элементов

Используйте полный путь индексов для обновления отдельной ячейки, а для добавления новой строки используйте [] или array_push():

$employees[0]["salary"] = 70000;        // update one field
$employees[] = ["name" => "Dan", "salary" => 60000]; // add a row
array_pop($employees);                   // remove the last row

array_pop() удаляет и возвращает последнюю строку, поэтому две операции выше взаимно отменяются.

Преобразование с помощью array_map и array_column

array_map() применяет функцию обратного вызова к каждому элементу. Чтобы преобразовать каждую ячейку, примените вложенный array_map к каждой строке:

Привести все значения двумерного массива к верхнему регистру

$grid = [["a", "b"], ["c", "d"]];

$upper = array_map(function ($row) {
    return array_map("strtoupper", $row);
}, $grid);
// $upper is [["A", "B"], ["C", "D"]]

Когда внутренние массивы являются записями, array_column() извлекает одно поле из каждой строки в плоский массив — идеально для получения одного столбца:

$employees = [
    ["name" => "Ann", "salary" => 65000],
    ["name" => "Bob", "salary" => 58000],
];

$names = array_column($employees, "name"); // ["Ann", "Bob"]
$total = array_sum(array_column($employees, "salary")); // 123000

Типичные ошибки

  • Смещение индексов на единицу. $grid[1][2] — это вторая строка, третий столбец — оба индекса начинаются с нуля.
  • Путаница порядка индексов. $employees[0]["name"] работает; $employees["name"][0] — нет, потому что внешний массив индексируется целыми числами.
  • Несуществующие ключи. Обращение к отсутствующей строке или столбцу генерирует предупреждение и возвращает null. Защищайтесь с помощью isset() или ?? default.
  • Функции, требующие рекурсии. Обычный count($arr) считает только верхний уровень — используйте count($arr, COUNT_RECURSIVE). Для обхода всех листьев используйте array_walk_recursive() вместо array_walk().
  • Семантика копирования. Массивы PHP копируются по значению, поэтому $copy = $original; с последующим изменением $copy[0][0] не меняет $original — в отличие от ссылок на объекты.

Заключение

Многомерные массивы позволяют представлять таблицы, сетки и сгруппированные записи, вкладывая один массив в другой. Читайте и записывайте отдельные ячейки через цепочку индексов [], выполняйте итерацию с помощью вложенных циклов foreach, а также преобразовывайте данные с помощью array_map(), array_column() и рекурсивных функций массивов. Для более широкого обзора инструментария массивов PHP смотрите PHP Arrays.

Практика

Практика
Что такое многомерные массивы в PHP?
Что такое многомерные массивы в PHP?
Was this page helpful?