用 is_array() 判断子项并递归调用,配合 foreach 遍历求和;array_sum() 仅处理一维数组,遇嵌套会丢失数据。

PHP8 递归函数怎么处理多维数组求和
直接结论:用 is_array() 判断子项,配合 foreach 遍历 + 自调用,别用 array_sum() 一步到位——它只扁平化一层,对嵌套数组无效。
为什么 array_sum() 不行
array_sum() 只对「一维数组」中所有数值元素求和;遇到子数组时,会把它当 0 处理(PHP 类型转换规则),导致结果丢失:
var_dump(array_sum([1, [2, 3], 4])); // 输出 int(5),不是 10
- 子数组
[2, 3]被转成布尔true→ 整型1,再被当成非数值忽略,最终只加了1 + 4 = 5 - PHP8 没改变这个行为,所以不能依赖它处理多层
手写递归函数的正确写法
核心逻辑:逐层展开,遇数组就进下一层,遇数字就累加,其他类型(如字符串数字、null)按需过滤或转换。
function sumNestedArray($arr): float {
$sum = 0;
foreach ($arr as $item) {
if (is_array($item)) {
$sum += sumNestedArray($item);
} elseif (is_numeric($item)) {
$sum += (float) $item;
}
// 忽略字符串、bool、object 等非数值类型
}
return $sum;
}
- 必须用
is_array()判断,不能用isset($item[0])或count($item),否则会把字符串误判为数组 - 返回类型声明
: float更安全,避免整数溢出或小数丢失(比如含3.14时) - PHP8 的联合类型(如
mixed)可省略参数类型,但加is_numeric()校验比靠类型声明更可靠
容易踩的坑:引用、无限递归与性能
常见错误不是语法问题,而是逻辑失控:
立即学习“PHP免费学习笔记(深入)”;
- 没检查循环引用(比如
$arr['parent'] = &$arr),会导致无限递归崩溃 —— PHP8 会抛出Fatal error: Allowed memory size exhausted - 传入非数组值(如
null、false)不校验,foreach会警告 —— 建议开头加if (!is_array($arr)) return 0; - 深度嵌套(>100 层)可能触发 PHP 默认的
xdebug.max_nesting_level限制(通常 256),需调大或改用栈模拟迭代 - 如果数组极大但层数浅,递归开销不大;若层数深但每层元素少,考虑用
RecursiveIteratorIterator+RecursiveArrayIterator迭代替代,避免栈溢出
最简健壮版建议加两行防御:
function sumNestedArray($arr): float {
if (!is_array($arr)) return 0;
$sum = 0;
foreach ($arr as $item) {
$sum += is_array($item)
? sumNestedArray($item)
: (is_numeric($item) ? (float) $item : 0);
}
return $sum;
}
递归本身不难,难的是想清楚「谁该进下一层」「谁该转成数」「谁该被丢弃」——这三类判断漏掉一个,结果就不可信。



















