array_walk() aplica un callback a cada elemento de un array pasándolo por referencia. La diferencia clave respecto a array_map() es que array_walk() modifica el array original en lugar de devolver uno nuevo, y el callback recibe tanto el valor como la clave. array_walk_recursive() hace lo mismo pero desciende a todos los niveles de arrays anidados.
Sintaxis
<?php array_walk(array|object &$array, callable $callback, mixed $arg = null): bool array_walk_recursive(array|object &$array, callable $callback, mixed $arg = null): bool ?>
El callback recibe el valor por referencia (si lo declaras con &), la clave y opcionalmente el tercer argumento de array_walk():
<?php
$nombres = ['ana', 'carlos', 'MARTA', 'luís'];
// Normalizar a Title Case: modifica el array original
array_walk($nombres, function(&$nombre) {
$nombre = mb_convert_case(trim($nombre), MB_CASE_TITLE, 'UTF-8');
});
print_r($nombres);
// Array ( [0] => Ana [1] => Carlos [2] => Marta [3] => Luís )
?>
El callback también recibe la clave
<?php
$precios = ['camiseta' => 19.90, 'pantalon' => 39.90, 'zapatillas' => 89.90];
array_walk($precios, function(&$precio, $producto) {
echo "$producto: " . number_format($precio, 2, ',', '.') . " n";
$precio = round($precio * 1.21, 2); // aplicar IVA
});
// camiseta: 19,90
// pantalon: 39,90
// zapatillas: 89,90
print_r($precios);
// Array ( [camiseta] => 24.08 [pantalon] => 48.28 [zapatillas] => 108.78 )
?>
El tercer argumento como datos adicionales
<?php
$descripciones = [
'intro' => 'Aprende PHP desde cero',
'avanzado' => 'Traits, generadores y fibers',
'testing' => 'PHPUnit y test doubles',
];
// Pasar el prefijo como dato extra
array_walk($descripciones, function(&$desc, $clave, $prefijo) {
$desc = "[$prefijo] $desc";
}, 'CURSO');
print_r($descripciones);
// Array ( [intro] => [CURSO] Aprende PHP desde cero ... )
?>
array_walk_recursive(): modificar arrays anidados
<?php
$catalogo = [
'ropa' => [
'camiseta' => ' Camiseta básica ',
'pantalon' => "t Pantalón chino n",
],
'calzado' => [
'zapatillas' => ' Zapatillas running ',
],
];
// Limpiar espacios en todos los niveles
array_walk_recursive($catalogo, function(&$valor) {
if (is_string($valor)) {
$valor = trim($valor);
}
});
print_r($catalogo);
// Array ( [ropa] => Array ( [camiseta] => Camiseta básica [pantalon] => Pantalón chino ) [calzado] => ... )
?>
Diferencias clave con array_map()
array_map()devuelve un nuevo array;array_walk()modifica el originalarray_walk()pasa la clave al callback;array_map()no (a menos que usesarray_keys()explícitamente)array_walk()permite pasar datos extra al callback mediante el tercer argumentoarray_walk_recursive()desciende a todos los niveles;array_map()es solo un nivel
<?php // array_map: más idiomático cuando quieres el resultado sin modificar el original $preciosConIva = array_map(fn($p) => round($p * 1.21, 2), $precios); // array_walk: cuando necesitas la clave o modificar el original en su lugar array_walk($precios, fn(&$p, $nombre) => ($p = round($p * 1.21, 2))); ?>
La documentación oficial de array_walk() y la de array_walk_recursive() explican el comportamiento con objetos y los cambios entre versiones.
