array_walk修改原数组,array_map返回新数组;前者需引用参数写回,后者必须return;参数顺序、回调签名、多数组支持、内存占用及适用场景均不同。

array_walk 修改原数组,array_map 返回新数组
这是最根本的差异。如果你需要直接改掉原始数组里的值,array_walk 是唯一选择;而 array_map 每次都会生成一个全新数组,原数组完全不受影响。
常见错误现象:用 array_map 写了回调函数去改 $v,结果打印原数组发现一点没变——因为 array_map 的回调函数里改的是副本,不是原变量。
-
array_walk回调的第一个参数必须加&$v才能真正写回原数组 -
array_map的回调函数必须有return,否则新数组全是null - 对关联数组操作时,
array_walk保留键名,array_map单数组时也保留键名,但多数组时键会变成数字索引
参数顺序和回调签名完全不同
array_walk 是「数组在前、函数在后」:array_walk($arr, $callback);array_map 则是「函数在前、数组在后」:array_map($callback, $arr)。这个顺序一旦写反,PHP 会直接报错或行为异常。
回调函数接收的参数也不同:
立即学习“PHP免费学习笔记(深入)”;
-
array_walk的回调默认接收两个参数:&$value、$key,第三个可选参数是$userdata(按值传入) -
array_map的回调参数个数必须和传入的数组个数一致。比如array_map($cb, $a, $b),那$cb就得接受两个参数:$a[i]和$b[i] - PHP 8.0+ 中,如果
array_map的回调声明了引用参数(如function(&$v)),会直接触发E_WARNING并中止执行
适用场景不能混用
想批量格式化字符串?用 array_map('strtoupper', $arr) 最干净;想给二维数组每个子项加个字段?array_walk 配合引用是唯一靠谱方式。
容易踩的坑:
- 用
array_filter或array_map去「修改」数组结构(比如 unset 某些键),实际只是生成新数组,原结构还在——这时候该用array_walk+ 引用 + 手动unset($arr[$key]),但注意:文档明确警告,array_walk过程中修改数组长度(增删元素)属于未定义行为,极可能 crash 或跳过元素 - 想把两个数组「拉链式」合并?
array_map(null, $a, $b)可以,但array_walk不支持多数组,硬写会报错 - 处理超大数组时,
array_map多一次内存拷贝,array_walk原地操作更省内存——但前提是真需要改原数组
第三方参数传递机制差异很大
array_walk 支持第三个参数 $userdata,它会被原样传给回调函数作为第三个参数,但它是按值传递的。如果你想通过它改变外部变量,回调里必须把对应形参声明为引用(function($v, $k, &$data)),否则外部变量不会变。
array_map 不提供类似机制。如果需要额外上下文,只能闭包捕获(use ($extra))或者封装成对象方法。
性能提示:频繁使用 use 捕获大量变量,或在回调里反复创建匿名函数,会轻微拖慢执行——这种细节在高并发脚本里值得留意。
真正容易被忽略的是:array_walk 对空数组返回 true,array_map 对空数组返回空数组;两者都无视内部指针位置,但 array_walk 在遍历时若回调里调用了 next() 或重置指针,行为不可靠——别这么干。



















