最稳妥的PHP嵌套数组展平方式是手动编写递归函数,因array_walk_recursive仅遍历叶子节点且不返回新数组,无法实现结构重组;自定义函数支持深度控制、键名保留/丢弃等需求。

PHP 处理嵌套数组最稳妥的方式是自己写递归函数,array_walk_recursive 不能替代展平(flatten)操作,它只遍历叶子节点,不改变结构。
为什么 array_walk_recursive 不能用来展平数组
它设计目标是「访问」所有标量值,不是「重组」数组。遇到子数组直接跳过,不会把它们的元素提上来。
- 输入
[1, [2, [3, 4]], 5],array_walk_recursive能拿到1、2、3、4、5,但无法生成新数组[1,2,3,4,5] - 它没有返回值,所有修改必须靠引用传参或闭包捕获变量,代码易错且难调试
- 无法控制展平深度(比如只展平一层),也不支持保留键名/丢弃键名等常见需求
手动递归展平:支持键名保留与深度控制
用递归函数可控性最强,也最容易理解逻辑。下面这个版本默认展平全部层级,支持可选参数:
function flatten_array($arr, $depth = null, $preserve_keys = true) {
$result = [];
foreach ($arr as $key => $value) {
if (is_array($value) && ($depth === null || $depth > 0)) {
$sub = flatten_array($value, $depth === null ? null : $depth - 1, $preserve_keys);
if ($preserve_keys) {
$result += $sub; // 合并时保留键名,可能覆盖同名键
} else {
$result = array_merge($result, $sub);
}
} else {
$result[$preserve_keys ? $key : count($result)] = $value;
}
}
return $result;
}
- 调用
flatten_array([1, [2, [3]]])→[1,2,3] - 加
$preserve_keys = false可避免键名冲突,适合纯数值场景 - 设
$depth = 1只展平第一层:输入[1, [2, [3]], [4]]→[1,2,[3],4]
用 array_reduce + 匿名递归(PHP 7.4+)实现无副作用展平
如果偏好函数式风格,且 PHP 版本 ≥ 7.4,可用 array_reduce 配合自引用匿名函数,避免全局函数污染:
$flatten = function ($arr, $depth = null) use (&$flatten) {
return array_reduce($arr, function ($carry, $item) use ($flatten, $depth) {
if (is_array($item) && ($depth === null || $depth > 0)) {
return array_merge($carry, $flatten($item, $depth === null ? null : $depth - 1));
}
$carry[] = $item;
return $carry;
}, []);
};
- 这个版本天然不保留原始键名,适合简单展平
- 注意:PHP 7.4 才支持在
use中引用自身匿名函数;低版本会报Cannot use lexical variable $flatten by reference - 性能略低于普通递归函数,但语义更清晰,无副作用
真正要注意的是键名处理——大多数“展平失败”其实是因为没意识到 PHP 数组键名不是自动重排的,array_values 或 array_merge([]) 才是重置数字键的正确姿势,而不是指望某个递归函数自动帮你做。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











