Функция array_walk() в PHP: как использовать её для эффективной работы с массивами
Узнайте, как array_walk() в PHP применяет callback к каждому элементу массива, с примерами, подводными камнями и сравнением с array_map().
array_walk() — встроенная функция PHP, которая применяет callback к каждому элементу массива непосредственно в нём. В отличие от array_map(), которая строит и возвращает новый массив, array_walk() обходит существующий массив и позволяет изменять каждый элемент напрямую через ссылку. На этой странице рассматриваются синтаксис функции, случаи, когда стоит выбрать её вместо обычного цикла foreach или array_map(), типичные ошибки при изменении значений, а также способ обхода вложенных массивов с помощью array_walk_recursive().
Синтаксис
array_walk(array &$array, callable $callback, mixed $arg = null): true| Параметр | Обязательный | Описание |
|---|---|---|
$array | Да | Массив для обхода. Передаётся по ссылке, поэтому callback может изменять его элементы. |
$callback | Да | Вызываемый объект, выполняемый для каждого элемента. Его сигнатура: callback($value, $key, $arg). Чтобы изменить элемент, объявите первый параметр по ссылке: function (&$value) { ... }. |
$arg | Нет | Необязательный дополнительный аргумент, передаваемый третьим параметром в каждый вызов callback. |
array_walk() всегда возвращает true (возвращает false только при ошибке типа). Функция не возвращает изменённый массив — переданный массив изменяется непосредственно.
Зачем передавать
$valueпо ссылке? Без&callback получает копию каждого элемента, поэтому любые изменения теряются. Добавьте&(как вfunction (&$value)) — и ваши правки будут записаны обратно в исходный массив. Подробнее о callback — в разделах функции PHP и callable.
Примеры использования array_walk()
Пример 1: изменение массивов
Одно из основных применений array_walk() — изменение массивов. Благодаря возможности применять пользовательскую функцию к каждому элементу массива, это удобный способ преобразовать массив под конкретные нужды. Ниже приведён пример использования array_walk() для смены регистра всех элементов массива.
Пример PHP 1: изменение массивов
Вывод:
Array
(
[0] => APPLE
[1] => BANANA
[2] => CHERRY
)В этом примере мы сначала определяем массив из трёх элементов. Затем объявляем пользовательскую функцию change_case(), которая использует встроенную функцию PHP strtoupper() для перевода каждого элемента в верхний регистр. После этого применяем array_walk() для вызова change_case() на каждом элементе массива. Наконец, выводим изменённый массив с помощью print_r().
Пример 2: выполнение вычислений
Ещё одно мощное применение array_walk() — выполнение вычислений над массивами. Применяя пользовательскую функцию к каждому элементу, вы можете производить самые разные вычисления. Ниже показано, как с помощью array_walk() вычислить сумму всех элементов массива.
Пример 2: выполнение вычислений
Вывод:
The total sum is: 15В этом примере мы сначала определяем массив из пяти элементов. Затем объявляем анонимную функцию, которая прибавляет каждый элемент к накопленной сумме. Применяем array_walk() для вызова этой функции на каждом элементе массива. Наконец, выводим итоговую сумму с помощью оператора echo.
Пример 3: обход многомерных массивов
Обычная функция array_walk() посещает только элементы верхнего уровня, поэтому для вложенного массива callback будет получать внутренние массивы, а не конечные значения. Для вложенных данных используйте функцию-компаньон array_walk_recursive(), которая рекурсивно спускается в подмассивы и запускает callback для каждого конечного значения. В примере ниже мы переводим все строки двухуровневого массива в верхний регистр.
Пример PHP 3: работа с многомерными массивами
Вывод:
Array
(
[0] => Array
(
[0] => APPLE
[1] => BANANA
[2] => CHERRY
)
[1] => Array
(
[0] => ORANGE
[1] => GRAPE
[2] => PINEAPPLE
)
)array_walk_recursive() обходит структуру в глубину и вызывает change_case() для каждой конечной строки, сохраняя вложенную форму массива и переводя каждое значение в верхний регистр.
Типичные ошибки
- Забытый
&. Если первый параметр callback не является ссылкой (function (&$value)), ваши изменения молча отбрасываются. Это самая распространённая ошибка при работе сarray_walk(). - Возвращаемое значение ничего не делает.
array_walk()игнорирует всё, что возвращает callback. Запись изменений происходит только через параметр-ссылку. Если вместо этого вы хотите получить преобразованную копию, используйтеarray_map(). - Порядок параметров callback —
($value, $key)— сначала значение, затем ключ. Это противоположно тому, что ожидают некоторые разработчики. - Нельзя добавлять или удалять ключи. Установка
$array = nullвнутри callback или изменение структуры массива в процессе обхода приводят к неопределённому поведению. Используйтеarray_walk()только для преобразования значений на месте.
array_walk() vs. array_map() vs. foreach
| Инструмент | Изменяет на месте? | Возвращает | Лучше использовать для |
|---|---|---|---|
array_walk() | Да (через ссылку) | true | Изменения существующего массива или выполнения побочного эффекта для каждого элемента |
array_map() | Нет | Новый массив | Получения преобразованной копии без изменения оригинала |
foreach | Да (с &$value) | — | Общей итерации с break/continue и полным управлением потоком |
array_reduce() | Нет | Одно значение | Свёртки массива до одного результата (сумма, конкатенация и т. д.) |
Выбирайте array_walk(), когда нужно сохранить тот же массив и изменить его значения на месте, или когда требуется, чтобы callback получал и значение, и ключ. Выбирайте array_map(), когда хотите получить новый массив, не трогая исходный.
Заключение
array_walk() применяет callback к каждому элементу массива непосредственно в нём — это чистый способ преобразовывать значения, выполнять побочные эффекты для каждого элемента или обрабатывать пары ключ/значение без написания явного цикла. Помните: передавайте значение по ссылке, если планируете его изменять; используйте array_walk_recursive() для вложенных массивов; отдавайте предпочтение array_map(), когда хотите создать новый массив, а не изменять оригинал. Подробнее об итерации по массивам — в разделах массивы PHP и цикл foreach.