在沒有資料庫、純以檔案系統管理圖片的情境下,一個能掃描目錄 → 產生縮圖 → 分頁顯示**的瀏覽器非常實用。本文解析一個單一檔案的 thumb.php,包含目錄遞迴、副檔名過濾、縮圖即時運算、HTML 表格佈局與分頁導航,適合快速部署相簿、素材庫或後台媒體管理器。
dirtoarray():掃描 $browsedir,過濾 $extensions (jpg/jpeg/gif/png),回傳檔名陣列。showdir():依 $maxcols、$maximages 計算分頁,對每張圖呼叫 getimagesize() 計算等比縮放尺寸,輸出 HTML 表格。pagemenu():產生分頁連結,每頁固定顯示 4 張 (2欄×2列)。<?php
// 設定區
$browsedir = "./images";
$extensions = ['jpeg','jpg','gif','png'];
$maxcols = 2; $maximages = 6; // 每頁 2x3 = 6 張
$imagemaxwidth = 100; $imagemaxheight = 100; // 縮圖最大邊長
// 1. 掃描目錄
function dirtoarray($browsedir, $extensions) {
$adirectory = []; $idirectory = 0;
$dir = dir($browsedir);
while ($entry = $dir->read()) {
if ($entry==='.' || $entry==='..') continue;
$ext = strtolower(pathinfo($entry, PATHINFO_EXTENSION));
if (in_array($ext, $extensions)) $adirectory[++$idirectory] = $entry;
}
$dir->close();
return $adirectory;
}
// 2. 顯示縮圖表格 (含分頁)
function showdir($adirectory, $start) {
global $browsedir, $maxcols, $maximages, $imagemaxwidth, $imagemaxheight;
$imagemaxratio = $imagemaxwidth / $imagemaxheight;
$ndir = count($adirectory);
$maximages = $start + ($maximages - 1); // 結束索引
echo "<table width=600>\n";
for ($i=$start; $i<=$maximages && $i<$ndir;) {
echo " <tr>\n";
for ($c=1; $c<=$maxcols; $c++) {
if ($i >= $ndir) break;
$imgfile = $adirectory[++$i];
$imgpath = "$browsedir/$imgfile";
$size = @getimagesize($imgpath);
if (!$size) continue;
$iw = $size[0]; $ih = $size[1];
$ratio = $iw/$ih;
if ($ratio > $imagemaxratio) {
$ow = $imagemaxwidth; $oh = ceil($imagemaxwidth/$iw*$ih);
} elseif ($ratio < $imagemaxratio) {
$oh = $imagemaxheight; $ow = ceil($imagemaxheight/$ih*$iw);
} else { $ow = $imagemaxwidth; $oh = $imagemaxheight; }
echo " <td align=center>\n";
echo " <a href='$imgpath'><img src='$imgpath' width=$ow height=$oh></a><br>$imgfile\n";
echo " </td>\n";
}
echo " </tr>\n";
}
echo "</table>\n";
pagemenu($browsedir, $ndir, $start);
}
// 3. 分頁選單
function pagemenu($browsedir, $ndir, $pg) {
echo "<br><center><font size=1>page: ";
$pgnum = 1;
for ($imgnum=0; $imgnum<=$ndir; $imgnum+=4) { // 每頁 4 張 (原碼邏輯)
$active = ($pg == $imgnum) ? 'class="active"' : '';
echo "<span $active><a href='?browsedir=$browsedir&start=$imgnum'>$pgnum</a></span> ";
$pgnum++;
}
echo "</font></center>";
}
// 主程式
$start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
$files = dirtoarray($browsedir, $extensions);
showdir($files, $start);
?>
| 技術點 | 實作細節 |
|---|---|
| 副檔名不區分大小寫 | strtolower(pathinfo($entry, PATHINFO_EXTENSION)) |
| 等比縮放演算法 | 比較原圖長寬比與最大框長寬比,決定以寬或高為基準 |
| 分頁邏輯 | URL 參數 start 為陣列索引起始,每頁固定筆數 |
| 錯誤抑制 | @getimagesize() 避免損壞檔案噴警告 |
| XSS 防護 | 檔名直接輸出 HTML,建議 htmlspecialchars() |
$browsedir = realpath($browsedir),確保在允許根目錄下。thumbs/,避免每次請求重複 getimagesize 運算。scandir() 會吃光記憶體,改用 DirectoryIterator + 計數器分頁。header('Content-Type: text/html; charset=utf-8')。// Controller
public function index(Request $request) {
$dir = storage_path('app/public/images');
$files = collect(glob("$dir/*.{jpg,jpeg,gif,png}", GLOB_BRACE))
->map(fn($p) => basename($p))
->paginate(12); // 自動分頁
return view('gallery', ['files' => $files, 'dir' => 'storage/images']);
}
// View (gallery.blade.php)
@foreach($files as $file)
<a href="{{ asset($dir.'/'.$file) }}" target="_blank">
<img src="{{ asset($dir.'/'.$file) }}" width="150" loading="lazy">
</a>
@endforeach
{{ $files->links() }}
這個單一檔案縮圖瀏覽器展示了 PHP 檔案系統操作、GD 尺寸運算、HTML 表格佈局與分頁的經典組合。雖然程式碼風格較舊 (全域變數、混合 HTML/PHP),但邏輯完整、零依賴,適合快速部署靜態相簿。現代專案建議採用前後端分離 + 物件儲存 (S3/OSS) + CDN架構,前端用 react-dropzone/masonry 做無限滾動畫廊,後端只提供 API 列表。