array_walk_recursive是拍平单层嵌套数组最快最轻量的选择,自动遍历叶子值并丢弃键名,适合纯值嵌套;遇对象或资源跳过,不支持深度控制。

用 array_walk_recursive 最快拍平单层嵌套
如果数组只有 1 层嵌套(比如 ['a', ['b', 'c'], 'd']),array_walk_recursive 是最轻量、最直接的选择。它自动跳过键名,只遍历叶子节点值,天然适合“拍平”场景。
注意它会丢弃所有中间键名,且不保留原始结构层级信息——这正是你想要的“扁平化”效果。
- 只适用于纯值嵌套,遇到对象或资源会跳过(不报错)
- 无法控制递归深度,遇到深层嵌套会全展开
- 示例:
$arr = ['a', ['b', 'c'], 'd']; $result = []; array_walk_recursive($arr, function($v) use (&$result) { $result[] = $v; }); // $result === ['a', 'b', 'c', 'd']
需要保留键名?得手写递归 + foreach
array_walk_recursive 不返回键名,如果你依赖键(比如 ['user' => ['name' => 'Tom']] 想变成 ['user.name' => 'Tom']),就必须自己递归拼接。
关键点在于:每次进入子数组时,把当前键追加到前缀里;遇到非数组值时,用拼好的键存入结果。
- 前缀分隔符建议用
.或_,避免和原始键名冲突 - 要判断
is_array($value),否则对字符串调用foreach会警告 - 示例(带前缀):
function flattenWithKeys($arr, $prefix = '') { $result = []; foreach ($arr as $key => $value) { $newKey = $prefix === '' ? $key : $prefix . '.' . $key; if (is_array($value)) { $result += flattenWithKeys($value, $newKey); } else { $result[$newKey] = $value; } } return $result; }
json_encode + 正则?别这么干
有人用 json_encode 把数组转成字符串,再用正则匹配引号内的值,最后 json_decode 回来——这看似“通用”,实际问题一堆:
- 字符串里含双引号、反斜杠、Unicode 会破坏 JSON 结构,导致解析失败
- 数值、
null、布尔值会被当成字符串处理,类型丢失 - 性能差,还可能误匹配注释或字符串字面量里的内容
- 根本不是数组操作,而是文本 hack,稳定性为零
深层嵌套或含对象?考虑 IteratorIterator + RecursiveArrayIterator
当数组嵌套很深,或混合了 ArrayObject、自定义迭代器,原生函数可能不够用。RecursiveArrayIterator 能明确控制递归行为,配合 IteratorIterator 可以逐层展开。
它比手写递归更健壮,尤其在处理 SPL 对象或需中断递归时(比如只展平前两层)。
- 必须用
getChildren()获取子迭代器,不能直接foreach子项 - 遇到非数组/非可迭代项会自动跳过,不报错
- 示例(仅展平两层):
$it = new RecursiveIteratorIterator( new RecursiveArrayIterator($arr), RecursiveIteratorIterator::SELF_FIRST ); $result = []; foreach ($it as $key => $value) { if ($it->getDepth()
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











