array_map用于生成新数组,保留键名但多数组时索引化;array_walk用于就地修改原数组,始终保留键名,需引用传参且支持额外上下文。

两者表面看都是“对每个元素执行函数”,但设计目的和底层逻辑完全不同,不能互换使用。
返回值机制截然相反
array_map 一定返回一个新数组,原数组完全不受影响;array_walk 永远不返回数组,只返回布尔值(PHP 8.2+ 固定为 true),它的目标就是直接改原数组。
- 用 array_map 处理后必须接收返回值,否则结果就丢了
- 用 array_walk 修改值,必须在回调函数第一个参数加 & 引用符号,否则修改无效
- array_walk 的返回值不能用来取处理结果,它只是操作是否完成的信号
回调函数接收的参数不同
array_map 的回调默认只传元素值;array_walk 默认同时传值和键名,天然适配关联数组。
- array_map(function($v) { return $v * 2; }, $arr); —— 只能拿到值
- array_walk($arr, function(&$v, $k) { $v = "$k:$v"; }); —— 同时拿到键和值,且可改原值
- array_walk 还支持第三个参数 $userdata,方便传入额外上下文,array_map 不提供这个能力
对键名的处理方式不同
array_map 在单数组操作时会保留原始键名;但一旦传入多个数组,键名就会被丢弃,转为数字索引。array_walk 始终严格保留原始键名,不管数组是索引还是关联结构。
- 对 ['a' => 1, 'b' => 2] 用 array_map,结果仍是 ['a' => 2, 'b' => 4]
- 同样数组用 array_walk,键名 a、b 完全不变,只是值被就地更新
- 如果误用 array_map 处理需要键名逻辑的场景(比如按 key 分类拼接),容易出错
适用场景有明确分工
想“算出一个新数组”——选 array_map;想“就地更新当前数组”——选 array_walk。
- 批量格式化数据生成新列表 → array_map
- 给用户数组统一添加时间戳字段 → array_walk(配合引用)
- 需要根据键名做差异化处理(如跳过某些 key)→ array_walk 更自然

















