基准条件必须覆盖所有输入分支,需用严格比较(===)并穷举类型(如负数、null、字符串等),树结构要区分null与空子节点,深度限制仅为兜底而非替代正确基准。

基础情况判断必须覆盖所有输入分支
基础情况(base case)不是“大概能停住”,而是函数执行路径上所有可能输入都必须被某个明确条件捕获。常见错误是只写 if ($n == 0),但传入负数、null、字符串 "0" 或浮点数 0.0 时直接跳过,导致无限调用。
修正要点:
- 用严格比较:优先用
===而非==,避免类型隐式转换干扰判断 - 穷举输入类型:对数字类递归,检查
!is_int($n)或$n ;对数组/对象,先判 <code>empty($data)再判is_array($data) - 把基础情况放在函数最开头,不嵌套在其他逻辑里——比如别写成
if (some_precheck) { if ($n === 0) return 1; ... },而应单独一行if ($n
数组递归中 empty() 比 count() 更安全
用 count($arr) == 0 做终止条件,看似合理,但遇到未初始化变量、null、或 Traversable 对象时会触发警告甚至致命错误;empty($arr) 则天然兼容 null、false、0、空数组、空字符串等所有“空值”场景。
示例对比:
立即学习“PHP免费学习笔记(深入)”;
// ❌ 危险写法
function sumArray($arr, $i = 0) {
if ($i >= count($arr)) return 0; // $arr 为 null 时 fatal error
return $arr[$i] + sumArray($arr, $i + 1);
}
// ✅ 安全写法
function sumArray($arr, $i = 0) {
if (empty($arr) || $i >= count($arr)) return 0;
return $arr[$i] + sumArray($arr, $i + 1);
}
树形结构遍历要同时处理 null 和叶子节点
处理类似 JSON 解析、菜单树、DOM 节点这类嵌套结构时,“空节点”和“无子节点”是两种不同状态,不能混为一谈。只判 !$node 会漏掉值为 0 或 false 的合法节点;只判 empty($node->children) 又会忽略 $node 本身为 null 的情况。
正确做法:
- 第一层先判
$node === null,立即返回默认值 - 再判是否含子节点:用
isset($node->children) && !empty($node->children) - 若需访问属性,统一用
??提供兜底,如$node->value ?? ''
递归深度计数器不能替代基础情况
加 $depth 参数并设上限(如 if ($depth > 100) return;)是兜底手段,不是终止逻辑。它解决的是“出错了也别崩”,而非“本该自然结束”。一旦依赖它终止,说明基础情况本身有漏洞——比如本该在第 5 层结束的逻辑,因参数计算错误跑到第 101 层才靠计数器掐断,此时结果已错,只是没报错。
所以:
深度限制必须配合日志告警(如 error_log("Recursion forced exit at depth {$depth} for input: " . json_encode($input));),便于发现真实逻辑缺陷。



















