W3docs

Функция 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: изменение массивов

php— editable, runs on the server

Вывод:

Array
(
    [0] => APPLE
    [1] => BANANA
    [2] => CHERRY
)

В этом примере мы сначала определяем массив из трёх элементов. Затем объявляем пользовательскую функцию change_case(), которая использует встроенную функцию PHP strtoupper() для перевода каждого элемента в верхний регистр. После этого применяем array_walk() для вызова change_case() на каждом элементе массива. Наконец, выводим изменённый массив с помощью print_r().

Пример 2: выполнение вычислений

Ещё одно мощное применение array_walk() — выполнение вычислений над массивами. Применяя пользовательскую функцию к каждому элементу, вы можете производить самые разные вычисления. Ниже показано, как с помощью array_walk() вычислить сумму всех элементов массива.

Пример 2: выполнение вычислений

php— editable, runs on the server

Вывод:

The total sum is: 15

В этом примере мы сначала определяем массив из пяти элементов. Затем объявляем анонимную функцию, которая прибавляет каждый элемент к накопленной сумме. Применяем array_walk() для вызова этой функции на каждом элементе массива. Наконец, выводим итоговую сумму с помощью оператора echo.

Пример 3: обход многомерных массивов

Обычная функция array_walk() посещает только элементы верхнего уровня, поэтому для вложенного массива callback будет получать внутренние массивы, а не конечные значения. Для вложенных данных используйте функцию-компаньон array_walk_recursive(), которая рекурсивно спускается в подмассивы и запускает callback для каждого конечного значения. В примере ниже мы переводим все строки двухуровневого массива в верхний регистр.

Пример PHP 3: работа с многомерными массивами

php— editable, runs on the server

Вывод:

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.

Практика

Практика
Какова функциональность функции 'array_walk()' в PHP?
Какова функциональность функции 'array_walk()' в PHP?
Was this page helpful?