傳統縮圖處理通常在上傳時同步生成,但若需支援多種尺寸、裁剪模式、浮水印等變化組合,預先生成所有組合極其浪費儲存空間。本文實作「按需生成」機制:利用 Apache mod_rewrite 攔截不存在的縮圖請求,轉交 PHP 腳本即時生成並快取,後續請求直接由 Web Server 靜態服務。
/upload/ 目錄下(如 /upload/news/2013/07/21/1.jpg)。/supload/(如 /supload/news/2013/07/21/1.jpg)。createthumb.php,依設定生成縮圖並輸出。www/
├── PicThumb.class.php # 縮圖核心類別
├── ThumbConfig.php # 尺寸/模式/浮水印設定
├── upload/ # 原圖根目錄
│ └── news/2013/07/21/1.jpg
├── supload/ # 縮圖根目錄(需可寫)
│ ├── .htaccess # Rewrite 規則
│ ├── watermark.png # 浮水印圖片
│ └── createthumb.php # 入口腳本
<IfModule mod_rewrite.c>
RewriteEngine On
# 靜態檔案/連結/目錄直接通過
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# 其餘導向生成腳本
RewriteRule ^.*$ createthumb.php?path=%{REQUEST_URI} [NC,L]
</IfModule>
<?php
define('WWW_PATH', dirname(dirname(__FILE__)));
require WWW_PATH . '/PicThumb.class.php';
require WWW_PATH . '/ThumbConfig.php';
$logfile = WWW_PATH . '/createthumb.log';
$source_root = WWW_PATH . '/upload/';
$dest_root = WWW_PATH . '/supload/';
$path = isset($_GET['path']) ? $_GET['path'] : '';
if (!$path) exit();
// 從請求路徑推導類型與相對路徑
$relative = str_replace($dest_root, '', WWW_PATH . $path);
$type = substr($relative, 0, strpos($relative, '/'));
$config = isset($thumb_config[$type]) ? $thumb_config[$type] : null;
if (!$config || !isset($config['fromdir'])) exit();
// 原圖與目標實體路徑
$source = str_replace('/' . $type . '/', '/' . $config['fromdir'] . '/', $source_root . $relative);
$dest = $dest_root . $relative;
// 生成縮圖
$obj = new PicThumb($logfile);
$obj->set_config($config);
if ($obj->create_thumb($source, $dest)) {
ob_clean();
header('Content-Type: ' . mime_content_type($dest));
exit(file_get_contents($dest));
}
?>
<?php
$thumb_config = [
'news' => [
'fromdir' => 'news',
'type' => 'fit', // 等比縮放填滿
'width' => 100,
'height' => 100,
'bgcolor' => '#FF0000'
],
'news_1' => [
'fromdir' => 'news',
'type' => 'fit',
'width' => 200,
'height' => 200,
'bgcolor' => '#FFFF00'
],
'article' => [
'fromdir' => 'article',
'type' => 'crop', // 中心裁剪
'width' => 250,
'height' => 250,
'watermark' => WWW_PATH . '/supload/watermark.png'
]
];
| 模式 | 說明 | 適用場景 |
|---|---|---|
fit | 等比縮放至指定框內,不足處以背景色填充 | 商品列表圖、頭像 |
crop | 等比縮放填滿框,超出部分裁剪(中心對齊) | Banner、封面圖 |
scale | 單純等比縮放,不指定高寬其一 | 文章內文圖片 |
mod_rewrite:a2enmod rewrite && systemctl reload apache2。supload/ 目錄需 Web Server 寫入權限(chown www-data:www-data supload)。type 白名單防止任意路徑遍歷。此「按需生成 + Rewrite 快取」模式廣泛應用於 CDN 邊緣節點、圖床服務、CMS 縮圖系統,是處理大量圖片多尺寸變體的標準架構模式。