PHP多维数组降维不必须递归,但递归最可靠;array_walk_recursive()适合提取标量值却丢键和结构;自定义递归函数可控制层级、拼接键名;array_merge(...$arr)易因非数组元素报错且丢键。
不是必须,但绝大多数场景下递归是最可靠的方式。非递归写法(如迭代 + 栈)虽可行,但代码复杂度高、可读性差,且容易漏掉深层嵌套或键类型不一致的情况。实际项目中,array_walk_recursive() 能覆盖 80% 的“只要值不要键”的扁平化需求;若需保留路径、键名或控制层级深度,则必须手写递归函数。
array_walk_recursive() 时为什么丢了键和结构?array_walk_recursive() 只遍历「叶子节点」,自动跳过含子数组的中间层,且不提供当前键路径。它适合提取所有标量值,但无法还原原始键名或区分同名嵌套键。
array_walk_recursive($arr, function($v) { $flat[] = $v; }); —— $flat 作用域外不可见,且未声明引用$flat = [];
array_walk_recursive($arr, function($v) use (&$flat) {
$flat[] = $v;
});null、array、object 类型的值,只处理 string/int/float/bool
关键在参数设计:是否保留原始键路径、是否限制最大深度、是否过滤空值。下面是一个兼顾灵活性与健壮性的写法:
function flattenArray($arr, $prefix = '', $maxDepth = null, $depth = 0) {
$result = [];
if ($maxDepth !== null && $depth > $maxDepth) return $result;
foreach ($arr as $key => $value) {
$newKey = $prefix === '' ? (string)$key : $prefix . '_' . $key;
if (is_array($value)) {
$result += flattenArray($value, $newKey, $maxDepth, $depth + 1);
} else {
$result[$newKey] = $value;
}
}
return $result;
}
$prefix 控制键名拼接方式(如 'user_profile_name'),避免键冲突$maxDepth 设为 1 可只展开一层,适合处理「二维转一维」的常见需求+= 合并子数组,而非 array_merge(),避免数字键被重排is_array(null) 返回 false,但 is_array([]) 是 true,无需额外判空array_merge(...$arrays) 会报 Warning?这是常见误区:有人试图用 array_merge(...array_values($arr)) 强行“展开”多维数组,但 ... 展开操作要求每个元素都是数组,一旦某项是字符串或整数,就会触发 Warning: array_merge(): Argument #1 is not an array。

[[], [], []])['a', ['b' => 'c']])完全失效真正需要批量降维时,别绕开数据结构本质——先判断类型,再分发处理。递归不是银弹,但它是 PHP 数组嵌套语义下最贴近直觉的解法。