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

PHP GD 圖片輸出緩存至 Memcached 完整實作

     編輯:PHP 相關知識

以輸出緩衝區捕獲二進位圖片資料

GD 函式庫(imagejpeg、imagepng 等)預設直接輸出至瀏覽器,若要將圖片二進位資料存入 Memcached,需利用 PHP 輸出緩衝區(Output Buffering)攔截輸出。

核心儲存流程

<?php
// 1. 啟動輸出緩衝
ob_start();

// 2. 產生圖片(此處以 imagejpeg 為例)
// $newimage 為 imagecreatetruecolor() 等建立的 GD 資源
// $quality 為品質參數(0-100),第二參數設為 null/false 表示不輸出檔案
imagejpeg($newimage, null, $quality);

// 3. 獲取緩衝區內容(二進位字串)
$imageData = ob_get_contents();

// 4. 清空並關閉緩衝區
ob_end_clean();

// 5. 寫入 Memcached(假設 getMemcache() 回傳 Memcached 實例)
$mem = getMemcache();
$memKey = 'img_' . md5($uniqueIdentifier); // 自訂唯一鍵名
$mem->set($memKey, $imageData, 7200); // 快取 2 小時

// 6. 輸出給瀏覽器(或直接 echo $imageData)
header('Content-Type: image/jpeg');
echo $imageData;
?>

讀取並輸出流程

<?php
$mem = getMemcache();
$imageData = $mem->get($memKey);

if ($imageData !== false) {
    header('Content-Type: image/jpeg');
    header('Content-Length: ' . strlen($imageData));
    echo $imageData;
    exit;
}

// 快取未命中:重新產生圖片並存入快取(可重構為共用函式)
// ... 產生圖片邏輯 ...
?>

關鍵注意事項

  • 記憶體限制:大尺寸圖片二進位資料可能超過 Memcached 單項 1MB 限制(預設),需調整 -I 參數或改用 Redis(支援 512MB)。
  • Content-Type 必須正確:輸出前務必送出對應的 header('Content-Type: image/...'),否則瀏覽器無法正確渲染。
  • ETag/Last-Modified:建議搭配 HTTP 快取頭(Cache-Control、ETag),減少重複請求流量。
  • 錯誤處理:ob_get_contents() 失敗或 Memcached 連線失敗時,需有降級策略(直接輸出圖片、記錄日誌)。
  • 鍵名設計:包含圖片識別碼、尺寸、版本等資訊,便於失效與管理(如 img_{id}_{w}x{h}_v{version})。

進階:封裝為可複用類別

class GdCache {
    private $mem;
    private $ttl = 3600;

    public function __construct(Memcached $mem, $ttl = 3600) {
        $this->mem = $mem;
        $this->ttl = $ttl;
    }

    public function output($key, callable $generator, $mime = 'image/jpeg') {
        $data = $this->mem->get($key);
        if ($data !== false) {
            $this->sendHeaders($mime, strlen($data));
            echo $data;
            return;
        }

        ob_start();
        $generator(); // 內部呼叫 imagejpeg/png 等
        $data = ob_get_clean();

        $this->mem->set($key, $data, $this->ttl);
        $this->sendHeaders($mime, strlen($data));
        echo $data;
    }

    private function sendHeaders($mime, $length) {
        header("Content-Type: $mime");
        header("Content-Length: $length");
        header('Cache-Control: public, max-age=' . $this->ttl);
    }
}

// 使用方式
$cache = new GdCache(getMemcache(), 7200);
$cache->output('chart_user_123', function() {
    // 繪圖邏輯
    $im = imagecreatetruecolor(400, 300);
    // ...
    imagejpeg($im, null, 90);
    imagedestroy($im);
});
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved