array_walk

Applies a user callback to every element of an array, optionally modifying values in place.

Signature
array_walk(array|object &$array, callable $callback, mixed $arg = null): true
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$arrayarray|objectThe array to walk. Passed by reference, so the callback can modify its values.
$callbackcallableCalled once per element as callback($value, $key) — or callback($value, $key, $arg) when arg is supplied. Declare the first parameter as &$value to change the array.
$argoptionalmixed= nullAn extra value passed as the third argument to every callback invocation.

Return value

trueAlways returns true. Since PHP 8.2.0 the declared return type is true; before that it was bool.

Errors

Throws ArgumentCountError if the callback requires more parameters than array_walk supplies (more than two, or more than three when arg is given). Emits E_WARNING if the callback declares its second or third parameter by reference.

Changelog

  • PHP 8.2.0The return type is true now; previously it was bool.
  • PHP 8.0.0If the callback expects its second or third parameter to be passed by reference, an E_WARNING is emitted.
  • PHP 7.1.0An ArgumentCountError is thrown if the callback requires more than 2 parameters (or more than 3 when arg is supplied). Previously an E_WARNING was generated.

array_walk runs a callback once for every element of an array. Unlike array_map, it does not build a new array — it hands the callback the value and the key, and lets you edit the original array in place by taking the value by reference.

When to reach for it

Reach for array_walk when the transformation needs the key, or when you want to mutate an existing array rather than allocate a copy. Normalising an associative config array, trimming user input keyed by field name, or appending an audit line per row are all natural fits. If you only need the values and want a fresh array back, array_map reads better.

What trips people up

The most common mistake is forgetting the ampersand:

array_walk($items, function ($value) { $value = strtoupper($value); }); // does nothing
array_walk($items, function (&$value) { $value = strtoupper($value); }); // works

The second trap is arity. Since PHP 7.1 a callback that declares more parameters than array_walk passes throws an ArgumentCountError instead of warning, so a three-parameter callback used without $arg is a fatal error.

You also cannot change the array's shape from inside the callback — adding, unsetting or reordering keys during the walk is undefined behaviour. Keys themselves are read-only.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Trim and lowercase every value in a submitted form array in place.
  • Apply a per-item tax or discount rate passed in as the third argument.
  • Build a log line per row using both the key and the value without allocating a second array.

Frequently asked questions

What is the difference between array_map and array_walk?

array_map returns a new array and leaves the original untouched, while array_walk modifies the original in place and always returns true. array_walk also passes the key to the callback, which array_map does not do for a single array.

Why is array_walk not changing my array?

The callback's first parameter must be declared by reference, as function (&$value). Without the ampersand the callback receives a copy and your assignment is discarded.

Can array_walk unset or add elements?

No. The array's structure must stay fixed for the duration of the walk — adding, removing or reordering elements inside the callback is undefined behaviour. Build a new array with array_filter or a foreach loop instead.

More examples

Using the key as well as the value

Without an ampersand the callback is read-only, which is exactly what you want for reporting. The output shows each key padded to five columns next to its exported value: host = 'localhost', port = 5432, ssl = true.

Example · php
<?php
$config = ['host' => 'localhost', 'port' => 5432, 'ssl' => true];

array_walk($config, function ($value, $key) {
    printf("%-5s = %s\n", $key, var_export($value, true));
});

array_walk returns true, not the array

The return value is always true, so writing $names = array_walk(...) destroys your data. The mutation lands on the original variable because it was passed by reference; print_r shows the trimmed names while var_dump shows the useless bool(true).

Example · php
<?php
$names = ['  Ada ', 'Grace  ', ' Linus'];

$result = array_walk($names, function (&$v) { $v = trim($v); });

var_dump($result);   // bool(true) — NOT the array
print_r($names);     // the original array, now trimmed

Too many callback parameters is fatal

Since PHP 7.1 this is an ArgumentCountError rather than a warning, so it aborts the loop before the first element is processed. Nothing from the callback's echo appears — only the catch block's message.

Example · php
<?php
try {
    $items = [1, 2, 3];
    // No third argument given, but the callback demands one.
    array_walk($items, function ($v, $k, $extra) { echo $v; });
} catch (ArgumentCountError $e) {
    echo "ArgumentCountError: callback wanted an argument array_walk never sent\n";
}

Discussion

  • Be the first to comment on this lesson.