本文提供一個實用的 PHP 函數,從指定資料夾隨機挑選一張圖片並直接輸出圖片二進位內容,適用於部落格側邊欄隨機照片、廣告輪播、驗證碼圖片等場景。
<?php
/**
* 隨機顯示圖片
* 用法:
* <img src="img.php">
* <img src="img.php?folder=images2/">
*/
function showRandomImage() {
// 1. 取得資料夾參數,預設為 /images/
$folder = isset($_GET['folder']) ? $_GET['folder'] : '/images/';
// 安全性:防止目錄遍歷攻擊
$folder = str_replace(['../', '..\\'], '', $folder);
$folder = trim($folder, '/\\');
if ($folder === '') $folder = 'images';
// 2. 組合實體路徑
$basePath = $_SERVER['DOCUMENT_ROOT'] . '/' . $folder;
if (!is_dir($basePath)) {
header('HTTP/1.1 404 Not Found');
exit('資料夾不存在');
}
// 3. 掃描圖片檔案
$allowedExt = ['gif', 'jpg', 'jpeg', 'png', 'webp'];
$files = [];
$handle = opendir($basePath);
if ($handle) {
while (false !== ($file = readdir($handle))) {
if ($file === '.' || $file === '..') continue;
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (in_array($ext, $allowedExt, true)) {
$files[] = $file;
}
}
closedir($handle);
}
if (empty($files)) {
header('HTTP/1.1 404 Not Found');
exit('資料夾無圖片');
}
// 4. 隨機選取
$randomFile = $files[array_rand($files)];
$filePath = $basePath . '/' . $randomFile;
// 5. 根據副檔名輸出正確 Content-Type
$ext = strtolower(pathinfo($randomFile, PATHINFO_EXTENSION));
$mimeTypes = [
'gif' => 'image/gif',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'webp' => 'image/webp',
];
header('Content-Type: ' . ($mimeTypes[$ext] ?? 'application/octet-stream'));
// 建議加上快取標頭(視需求調整)
header('Cache-Control: public, max-age=3600');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
// 6. 輸出圖片二進位內容
readfile($filePath);
exit;
}
showRandomImage();
?>
<!-- 預設資料夾 /images/ -->
<img src="img.php" alt="隨機圖片">
<!-- 指定資料夾 -->
<img src="img.php?folder=uploads/banners/" alt="隨機橫幅">
<!-- 作為 CSS 背景(需搭配 JS 或接受動態變化) -->
<div style="width:300px; height:200px; background:url('img.php?folder=bg/') center/cover no-repeat;"></div>
10_pic.jpg 表示權重 10,解析前綴計算加權隨機。$_SERVER['HTTP_REFERER'] 僅允許自家域名嵌入。RecursiveDirectoryIterator。../,但建議進一步限定允許的資料夾白名單陣列。readfile() 直接輸出,若上傳處理不當可能輸出惡意檔案。生產環境應驗證檔案真實類型(finfo_file() 或 getimagesize())。@ 抑制。