首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 動態輸出圖片支援 CDN 快取(ETag + 304 Not Modified)

     編輯:PHP 相關知識

PHP 動態輸出圖片支援 CDN 快取(ETag + 304 Not Modified)

PHP 直接輸出圖片(如縮圖、水印)時,若無快取機制,CDN 會每次回源,造成後端壓力。解決方式:輸出 ETag(內容雜湊)與 Last-Modified,檢查請求標頭 If-None-Match / If-Modified-Since,相符則回傳 304 Not Modified,瀏覽器/CDN 直接使用快取。

核心程式碼片段

<?php
// 假設 $imageData 為二進位圖片資料(或檔案路徑)
$etag = md5($imageData);           // 內容指紋
$lastMod = gmdate('D, d M Y H:i:s', strtotime('2011-01-01')) . ' GMT'; // 固定或依檔案 mtime

// 檢查 ETag
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
    $clientETag = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"');
    if ($clientETag === $etag) {
        header('HTTP/1.1 304 Not Modified');
        exit;
    }
}

// 選擇性檢查 Last-Modified
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    $clientTime = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
    $serverTime = strtotime($lastMod);
    if ($clientTime >= $serverTime) {
        header('HTTP/1.1 304 Not Modified');
        exit;
    }
}

// 輸出快取標頭
header('ETag: "' . $etag . '"');
header('Last-Modified: ' . $lastMod);
header('Cache-Control: max-age=2592000, public'); // 30 天
header('Content-Type: image/jpeg'); // 依實際格式調整
echo $imageData;
?>

關鍵點說明

  • ETag 產生:以內容 md5() 或 sha1(),確保內容變更時 ETag 改變。若圖片為動態生成(如帶參數縮圖),需包含所有參數計算雜湊。
  • HTTP_IF_NONE_MATCH:Nginx/Apache 會自動將客戶端 If-None-Match 放入 $_SERVER,無需額外 FastCGI 參數設定。
  • Last-Modified:可用檔案 filemtime() 或固定版本日期。若動態生成無實體檔,建議用 ETag 為主。
  • Cache-Control:max-age 秒數 + public 允許 CDN 快取。
  • 304 回應:不得包含內容主體,直接 exit。

Nginx 設定補充

location /image.php {
    fastcgi_param HTTP_IF_NONE_MATCH $http_if_none_match;
    fastcgi_param HTTP_IF_MODIFIED_SINCE $http_if_modified_since;
    # 其他 fastcgi_param...
}

現代 Nginx 預設已將所有 HTTP 標頭對應至 $_SERVER['HTTP_*'],通常無需額外設定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved