PHP使用点分隔符生成适配FancyTree的文件目录树JSON视图
问题解决代码及方案
你现有代码的核心问题是每个文件独立生成完整路径树后直接追加到结果集,没有合并相同路径的公共目录,所以会产生重复的父节点,你尝试用array_merge_recursive也不好处理的原因是PHP自带的数组合并没法自动识别同title的目录为同一个节点。
解决思路
采用引用遍历的方式逐层匹配目录:
- 先拆分每个文件的URL为路径段数组,比如
dir.dir1拆成['dir', 'dir1'] - 从结果根节点开始遍历路径段,每一层如果不存在对应title的目录节点就新建,并且标记为folder类型
- 遍历到最后一层路径后,将当前文件节点追加到该目录的children数组中
完整修复代码
// 原有排序逻辑保留 $url = array_column($scriptArray, 'url'); array_multisort($url, SORT_ASC, $scriptArray); $result = []; foreach ($scriptArray as $item) { // 拆分路径为目录段数组 $pathSegments = explode('.', $item->url); // 用引用跟踪当前遍历的层级,初始指向根结果数组 $currentLevel = &$result; // 遍历所有目录段,逐层匹配/创建目录 foreach ($pathSegments as $seg) { // 查找当前层级下是否已存在同名目录 $existIndex = -1; foreach ($currentLevel as $index => $node) { if (isset($node['folder']) && $node['folder'] === true && $node['title'] === $seg) { $existIndex = $index; break; } } // 不存在就新建目录节点 if ($existIndex === -1) { $newFolder = [ 'title' => $seg, 'folder' => true, 'children' => [] ]; $currentLevel[] = $newFolder; $existIndex = count($currentLevel) - 1; } // 引用进入下一层级 $currentLevel = &$currentLevel[$existIndex]['children']; } // 最后将文件节点追加到末级目录的children里 $currentLevel[] = [ 'title' => $item->name . '.' . $item->type, 'key' => $item->id ]; // 销毁引用避免后续遍历污染 unset($currentLevel); } // 输出即可得到符合要求的JSON echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
验证说明
运行上述代码后输出的JSON结构完全匹配你需要的FancyTree兼容格式,公共目录会自动合并,同目录下的文件会归到同一个children数组中。
内容的提问来源于stack exchange,提问作者Andy Stubbs
相关产品推荐
相关产品推荐

