递归函数是精确计算PHP数组最大嵌套深度的唯一可靠方法:先判非数组返回0,空数组返回1,再遍历递归取各分支深度最大值加1。

用递归函数精确计算最大嵌套深度
PHP 没有内置函数直接返回数组的「最大嵌套深度」,count() 只能算当前层元素个数,is_array() 仅判断单层类型。真正可靠的方案是写一个递归函数,逐层探测并取所有分支中的最大值。
常见错误是只检查第一层子数组是否存在,忽略“不规则嵌套”——比如某个键下是二维,另一个键下是四维,这时必须遍历全部分支才能得出准确最大深度。
- 函数必须接收
$arr并先做is_array($arr)判断,非数组直接返回0 - 空数组
[]应视为深度1(它本身就是一个一维容器) - 对每个
$value调用自身后,取max($maxDepth, getArrayDepth($value) + 1),不能漏掉+1 - 避免在递归中使用全局变量或静态计数器,否则多路分支会互相污染
示例精简版:
function getArrayDepth($arr) {
if (!is_array($arr)) return 0;
if (empty($arr)) return 1;
$maxDepth = 0;
foreach ($arr as $value) {
$maxDepth = max($maxDepth, getArrayDepth($value) + 1);
}
return $maxDepth;
}
用 serialize() 快速估算但别依赖它
序列化字符串里每出现一次 a: 就代表一层数组结构,所以 substr_count(serialize($arr), 'a:') 能给出一个粗略总数。但它只统计所有 a: 出现次数,无法区分嵌套层级——比如 a:1:{i:0;a:2:{...}} 里有两个 a:,但实际深度是 2,不是 2 的总和。
立即学习“PHP免费学习笔记(深入)”;
这个方法适合调试时一眼扫出「大概有没有深层嵌套」,比如你预期是一维却看到结果 ≥ 3,就知道得去查结构了。但绝不能用于逻辑判断,尤其当数组含对象、资源或自定义序列化时,serialize() 行为不可靠。
- 不要用它做条件分支,如
if (substr_count(...) > 2) { ... } - 注意
serialize()会触发__sleep(),可能改变原始数据状态 - 大数组序列化开销明显,线上环境慎用
json_encode() + 正则匹配只适合轻量预判
把数组转成 JSON 后,最深的连续左方括号 [ 嵌套层数能反映维度倾向。例如 [[[1,2]]] 生成 [[[1,2]]],正则 /\[(?=\[)/ 可捕获前两个 [(第三个后面没 [,不匹配),返回深度 2。
但它本质是字符串模式分析,完全不理解 PHP 数组语义:关联键、混合键名、数字索引混用都会让结果失真;更严重的是,JSON 会丢弃 PHP 特有结构(如资源、闭包、引用),导致误判。
- 仅建议在 CLI 脚本或开发工具中临时用,比如写个
debug_depth($arr)辅助肉眼观察 - 永远要配合
is_array()兜底,避免传入null或字符串触发警告 - 遇到
json_encode()返回false(如含不可序列化类型),必须立刻 fallback 到递归函数
为什么 array_walk_recursive() 不能用来求深度
array_walk_recursive() 的设计目标是「扁平化访问所有叶子节点」,它会自动跳过中间的数组层,只回调最终非数组值。这意味着你根本拿不到任何层级信息——既不知道当前在第几层,也无法中断递归或记录路径。
有人试图在回调里用 debug_backtrace() 数调用栈深度,但这属于 hack 行为:性能差、不可移植、且在 opcache 开启时可能失效。真正需要深度信息时,必须自己控制递归过程。
-
array_walk_recursive()的回调函数签名是function($value, $key),没有深度参数 - 它内部实现是迭代+栈模拟,不是真实函数调用栈,
debug_backtrace()不可靠 - 若数组存在循环引用(如
$arr['ref'] = &$arr),该函数会无限执行直到内存耗尽
最大嵌套深度是个结构性指标,不是遍历行为的结果;所有绕过显式递归的取巧方式,最终都会在边界 case 上露出马脚——比如不规则嵌套、空数组、混合键型。老老实实用 getArrayDepth(),比任何字符串解析都稳。



















