PHP多维数组过滤与3D素材目录网格展示技术求助
Hey Sam! Let's fix this directory array filtering and traversal issue so you can show off those Substance Designer assets in a clean grid layout. Here's a step-by-step solution tailored to your setup:
1. First: Filter Out Empty Categories (Fix the Recursive Function)
Your current function returns empty arrays for categories like Ceramic or Concrete, which we don't want. Let's modify the recursive function to automatically skip any empty directories, so we only keep categories that have actual asset folders inside:
function listFolderFiles($dir) { $fileInfo = scandir($dir); $allFileLists = []; foreach ($fileInfo as $item) { // Skip . and .. directories if ($item === '.' || $item === '..') continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $item; if (is_dir($fullPath)) { // Recursively get content of the subdirectory $subDirContent = listFolderFiles($fullPath); // Only add this category/subfolder if it has content if (!empty($subDirContent)) { $allFileLists[$item] = $subDirContent; } } else { // For files, we'll just store the filename (you could store the full path if needed) $allFileLists[$item] = $item; } } return $allFileLists; } // Now $dirContent will only have Fabric and Wood (the non-empty categories) $dirContent = listFolderFiles('my_directory');
2. Traverse the Cleaned Array & Generate Grid Layout HTML
Next, we'll loop through the filtered array to build your grid. We'll extract preview images (looking for preview.jpg or image.jpg) and link to the .sbsar files, while using CSS Grid to make it look polished:
PHP Code for Rendering the Grid
<?php if (!empty($dirContent)): ?> <?php foreach ($dirContent as $category => $assets): ?> <section class="category-section"> <h2><?= htmlspecialchars($category) ?></h2> <div class="assets-grid"> <?php foreach ($assets as $assetFolder => $files): ?> <div class="asset-card"> <h3><?= htmlspecialchars($assetFolder) ?></h3> <!-- Find and display preview image --> <?php $previewPath = ''; foreach ($files as $fileName) { $lowerName = strtolower($fileName); if ($lowerName === 'preview.jpg' || $lowerName === 'image.jpg') { $previewPath = "my_directory/$category/$assetFolder/$fileName"; break; } } ?> <?php if ($previewPath): ?> <img src="<?= htmlspecialchars($previewPath) ?>" alt="Preview for <?= htmlspecialchars($assetFolder) ?>" class="asset-preview"> <?php else: ?> <div class="no-preview">No Preview Available</div> <?php endif; ?> <!-- Link to the .sbsar file --> <?php foreach ($files as $fileName): ?> <?php if (pathinfo($fileName, PATHINFO_EXTENSION) === 'sbsar'): ?> <?php $filePath = "my_directory/$category/$assetFolder/$fileName"; ?> <a href="<?= htmlspecialchars($filePath) ?>" class="asset-link"> <?= htmlspecialchars($fileName) ?> </a> <?php endif; ?> <?php endforeach; ?> </div> <?php endforeach; ?> </div> </section> <?php endforeach; ?> <?php else: ?> <p>No assets found in your directory.</p> <?php endif; ?>
CSS for the Grid Layout
Add this to your stylesheet to make the grid responsive and visually appealing:
/* Base styles for the category section */ .category-section { margin: 2rem auto; max-width: 1200px; padding: 0 1rem; } .category-section h2 { font-size: 1.5rem; color: #2d3748; margin-bottom: 1rem; border-bottom: 2px solid #e2e8f0; padding-bottom: 0.5rem; } /* Grid container for assets */ .assets-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; } /* Individual asset card */ .asset-card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); padding: 1.2rem; transition: transform 0.2s ease; } .asset-card:hover { transform: translateY(-4px); } .asset-card h3 { font-size: 1.1rem; color: #2d3748; margin-bottom: 1rem; } /* Preview image styles */ .asset-preview { width: 100%; height: 200px; object-fit: cover; border-radius: 4px; margin-bottom: 1rem; } .no-preview { width: 100%; height: 200px; background-color: #f7fafc; display: flex; align-items: center; justify-content: center; color: #718096; border-radius: 4px; margin-bottom: 1rem; } /* Download link styles */ .asset-link { display: inline-block; padding: 0.6rem 1.2rem; background-color: #3182ce; color: white; border-radius: 4px; text-decoration: none; font-size: 0.9rem; } .asset-link:hover { background-color: #2b6cb0; }
Key Notes:
- Security First: We use
htmlspecialchars()to escape all dynamic content (category names, filenames) to prevent XSS attacks. Never output user-generated content without escaping it! - Responsive Grid: The CSS uses
repeat(auto-fill, minmax(280px, 1fr))so the grid automatically adjusts to different screen sizes. - Flexible Preview Detection: The code looks for both
preview.jpgandimage.jpgsince your assets use both names. - Empty State Handling: We added a check for empty
$dirContentto show a friendly message if no assets are found.
This should give you a working grid layout that only shows non-empty categories, with each asset displayed in a card with a preview and download link.
内容的提问来源于stack exchange,提问作者Sam

