無需資料庫,直接掃描目錄文件系統即可構建簡單圖片相冊。本文提供完整代碼:opendir 遍歷、副檔名過濾、修改時間倒序、分頁邏輯、上一頁/下一頁/首尾頁導航。
<div style="width: 90%; margin: 10px auto; border: 1px solid #ccc; text-align: center">
<?php
$page = isset($_GET['page']) ? (int)$_GET['page'] : 0; // 0-based
$perPage = 10;
$imgDir = "upload";
$allowedExt = ['gif', 'jpg', 'jpeg', 'png', 'webp', 'bmp'];
$files = [];
$handle = opendir($imgDir);
while (false !== ($file = readdir($handle))) {
if ($file === '.' || $file === '..') continue;
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (!in_array($ext, $allowedExt, true)) continue;
$path = $imgDir . DIRECTORY_SEPARATOR . $file;
if (!is_file($path)) continue;
$files[$file] = filemtime($path); // 鍵=文件名,值=修改時間
}
closedir($handle);
// 按修改時間倒序
arsort($files);
$files = array_keys($files);
$total = count($files);
$totalPages = (int)ceil($total / $perPage) - 1; // 0-based 最大頁碼
// 當前頁切片
$offset = $page * $perPage;
$pageFiles = array_slice($files, $offset, $perPage);
// 輸出圖片
foreach ($pageFiles as $file) {
$url = $imgDir . '/' . rawurlencode($file);
echo '<div style="display:inline-block; margin:10px; text-align:center">';
echo '<img src="' . htmlspecialchars($url) . '" style="max-width:200px; max-height:200px"><br>';
echo htmlspecialchars($file) . '</div>';
}
// 分頁導航
echo '<div style="margin:20px 0">';
if ($page > 0) {
echo '<a href="?page=0">首頁</a> ';
echo '<a href="?page=' . ($page - 1) . '">上一頁</a> ';
}
if ($page < $totalPages) {
echo '<a href="?page=' . ($page + 1) . '">下一頁</a> ';
echo '<a href="?page=' . $totalPages . '">末頁</a>';
}
echo '<span style="margin-left:20px">第 ' . ($page + 1) . ' / ' . ($totalPages + 1) . ' 頁,共 ' . $total . ' 張</span>';
echo '</div>';
?>
</div>
opendir/readdir + pathinfo 取副檔名 + in_array 白名單。filemtime 取修改時間,arsort 保持鍵值關聯倒序。ceil(total/perPage) - 1 得最大頁碼。array_slice($files, $offset, $perPage) 取當前頁數據。htmlspecialchars 防 XSS,rawurlencode 處理中文文件名 URL。| 痛點 | 優化方案 |
|---|---|
| 大目錄掃描慢 | 緩存文件列表 (JSON/Redis),定時/事件驅動更新 |
| 無縮圖、大圖加載慢 | 上傳時同步生成縮圖 (Imagick/GD),顯示縮圖鏈接原圖 |
| 中文文件名亂碼 | 文件系統統一 UTF-8,或上傳重命名為 UUID + 原名存資料庫 |
| 無權限控制 | 引入 ACL:私有目錄驗證 Session/Token 後輸出 |
| 分頁跳轉 URL 不美觀 | URL Rewrite:/album/page/2 → ?page=1 |
DirectoryIterator / RecursiveDirectoryIterator (SPL) 替代 opendir,支援鏈式操作與過濾器。League\Flysystem 抽象存儲層,未來可無縫遷移至 S3/OSS。intervention/image 自動生成 WebP、多尺寸響應式圖片。幾十行代碼即可跑通「目錄掃描 → 分頁顯示」全流程,是快速構建內部圖片庫、產品圖管理、截圖歸檔等輕量場景的不二之選。