讲师中心 微信公众号
AI工具推荐 视频效率加速

PHP怎么递归遍历所有节点

风明同学_3982

风明同学_3982

发布时间:2026-09-10 14:55:25

|

612人浏览过

|

来源于php中文网

原创

recursiveDirectoryIterator需配合RecursiveIteratorIterator使用,显式传SKIP_DOTS避免无限循环,CHILD_FIRST适合清理;数组递归需判非数组终止,防栈溢出;array_walk_recursive仅处理叶子值;JSON需防循环引用。

php怎么递归遍历所有节点

用 recursiveIteratorIterator 配合 recursiveDirectoryIterator 遍历目录树

PHP 原生不提供“递归遍历任意嵌套节点”的通用函数,但对文件系统这种典型树形结构,recursiveDirectoryIterator 是最稳妥的选择。它天然支持符号链接处理、跳过 ./..、按需过滤类型,比手写 scandir() + 递归函数更健壮。

常见错误是直接用 foreach 遍历 recursiveDirectoryIterator 实例——它本身不可直接遍历,必须包一层 recursiveIteratorIterator:

$it = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('/path', RecursiveDirectoryIterator::SKIP_DOTS),
    RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($it as $file) {
    echo $file->getPathname() . "\n";
}
  • RecursiveDirectoryIterator::SKIP_DOTS 必须显式传入,否则会把 . 和 .. 当作真实目录遍历,导致无限循环
  • CHILD_FIRST 比默认的 SELF_FIRST 更适合清理场景(先处理子项再删父目录)
  • 若需只取文件或只取目录,用 $file->isFile() 或 $file->isDir() 判断,别依赖扩展名

手写递归函数遍历多维数组节点

当数据是 PHP 数组(比如从 JSON 解析来的树状结构),直接写递归函数最灵活。关键不是“能不能递归”,而是“怎么控制深度和中断”。

典型陷阱是没设终止条件或误判叶子节点:

立即学习“PHP免费学习笔记(深入)”;

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载
function traverseArray($data, $depth = 0) {
    if (!is_array($data)) {
        echo str_repeat('  ', $depth) . "leaf: {$data}\n";
        return;
    }
    foreach ($data as $key => $value) {
        echo str_repeat('  ', $depth) . "node: {$key}\n";
        traverseArray($value, $depth + 1);
    }
}
  • 必须先判断 !is_array($data),否则遇到字符串、数字等非数组值会报 Invalid argument supplied for foreach()
  • 如果数组可能含对象(如 stdClass),需额外加 is_object($data) && method_exists($data, '__toString') 分支
  • 深度过大时(如 >100 层),PHP 默认栈限制会触发 Fatal error: Maximum function nesting level,此时应改用栈模拟递归

用 array_walk_recursive() 处理纯值节点(不保留键和层级)

如果你只关心所有叶子值(比如批量转义 HTML、统一编码),array_walk_recursive() 是最轻量的选择。但它会跳过中间的数组键,也完全丢失层级信息。

它和手写递归的核心区别在于:不递归进入关联数组的键名,只深入到最终非数组/非对象的值。

$tree = ['a' => ['b' => 'val1'], 'c' => 'val2'];
array_walk_recursive($tree, function($val, $key) {
    echo "{$key}: {$val}\n"; // 输出 b: val1 和 c: val2,但 a 不会出现
});
  • 无法区分 'b' => 'val1' 是二级键还是顶级键,所有键一视同仁
  • 遇到对象时,仅当对象实现了 Traversable 才会被展开;否则整个对象作为叶子值传入回调
  • 不能修改原数组的键结构(它内部是值拷贝),要改结构必须用引用:function(&$val, $key)

JSON 树结构递归解析时注意循环引用

从 API 或数据库拿到的 JSON 数据若存在父子双向引用(如组织架构中部门有 parent_id 又有 children 数组),直接递归解析可能陷入死循环。

PHP 的 json_decode() 默认不会检测循环引用,需要手动标记已访问节点:

function safeTraverse($node, &$seen = []) {
    $id = is_object($node) ? spl_object_id($node) : (is_array($node) ? md5(serialize($node)) : null);
    if ($id && isset($seen[$id])) return;
    $seen[$id] = true;
    // ... 处理逻辑
}
  • 对数组用 md5(serialize($node)) 不可靠(顺序敏感、大数组性能差),更稳妥的是在原始数据里加唯一 id 字段并用它做键
  • 如果数据来自不可信来源,优先考虑用迭代方式 + 显式栈管理,避免爆栈
  • json_decode($json, true) 返回数组后,就不再有对象引用问题,但要注意数组内是否嵌套了 stdClass 对象
递归本身不难,难的是明确你要遍历的是什么结构、是否允许重复访问、有没有外部约束(如内存、超时、权限)。文件系统、数组、JSON 这三类场景的解法差异很大,别硬套同一个函数。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

11604

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

6701

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2175

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

4248

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

4954

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

3891

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

5617

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

4402

2023.11.13

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

120

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP函数之array数组函数视频讲解
PHP函数之array数组函数视频讲解

共76课时 | 29.2万人学习

墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn