如何在Laravel Blade模板中展示表示文件夹结构的数组?
解决PHP多维数组转嵌套文件夹HTML列表的重复渲染问题
问题背景
你有一个表示文件结构的扁平PHP数组:
$files = [ ["size" => "9.8 MiB", "name" => "Game.exe"], ["size" => "3.9 MiB", "name" => "Launcher.exe"], ["size" => "2 MiB", "name" => "USRDIR/mask.mpk"], ["size" => "1 MiB", "name" => "USRDIR/subs.hrt"], ["size" => "10 MiB", "name" => "USRDIR/fullhd/footage.mkv"], ];
需要生成嵌套的HTML无序列表展示文件夹结构,但当前实现会重复渲染同一文件夹(比如USRDIR会因为多个文件在其中而多次输出)。
解决方案:先转树形结构,再递归渲染
正确的做法是先在控制器中将扁平数组转换为嵌套树形结构,再在Blade模板中递归渲染,这样就能避免重复文件夹的问题。
第一步:控制器中构建树形结构
将扁平的文件数组转换为嵌套的树形结构,每个文件夹只保留一个节点,文件放在对应层级下:
// 原始$files数组处理 $fileTree = []; foreach ($files as $file) { $pathParts = explode('/', $file['name']); $currentNode = &$fileTree; foreach ($pathParts as $index => $part) { $isFile = ($index === count($pathParts) - 1); if ($isFile) { // 添加文件节点 $currentNode[] = [ 'type' => 'file', 'name' => $part, 'size' => formatBits($file['size']) // 假设formatBits是你已有的格式化函数 ]; } else { // 检查当前层级是否已存在该文件夹 $folderFound = false; foreach ($currentNode as &$node) { if ($node['type'] === 'folder' && $node['name'] === $part) { $currentNode = &$node['children']; $folderFound = true; break; } } // 不存在则创建新文件夹节点 if (!$folderFound) { $newFolder = [ 'type' => 'folder', 'name' => $part, 'children' => [] ]; $currentNode[] = $newFolder; $currentNode = &$newFolder['children']; } } } unset($currentNode); // 释放引用,防止后续遍历出错 } return view('single', ['fileTree' => $fileTree]);
第二步:Blade模板递归渲染树形结构
创建一个局部视图resources/views/partials/file-tree.blade.php,用于递归渲染节点:
<ul @if($isRoot) class="root-folder" @else class="folder" @endif> @foreach($nodes as $node) @if($node['type'] === 'folder') <li> <span class="file-icon">🗀</span>{{ $node['name'] }} <!-- 递归渲染子节点 --> @include('partials.file-tree', ['nodes' => $node['children'], 'isRoot' => false]) </li> @else <li class="file"> <span class="file-icon">🗋</span>{{ $node['name'] }} <span class="file-size">({{ $node['size'] }})</span> </li> @endif @endforeach </ul>
然后在主视图single.blade.php中引入这个局部视图:
@include('partials.file-tree', ['nodes' => $fileTree, 'isRoot' => true])
为什么之前的实现会重复渲染?
原来的代码是将每个文件的路径拆分后逐个输出,同一个文件夹会因为包含多个文件而被多次遍历输出。而转换为树形结构后,每个文件夹在结构中仅存在一次,递归渲染时自然只会生成一次对应的节点,彻底解决重复问题。
内容的提问来源于stack exchange,提问作者user21083546
相关产品推荐
相关产品推荐

