2012-06-23 31 views
2

好吧,所以我有一個想法,我想如何服務和緩存我的圖像。 我不知道這是否是正確的做法,但如果是這樣,我想知道如何去防止濫用。創建調整大小的圖像緩存,但防止濫用

情況:

的index.php

<img src="images/cache/200x150-picture_001.jpg" /> 

圖像/高速緩存/ htaccess的

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ images/image.php?f=$1 [L] 

上述檢查如果圖像存在,如果不將是改寫爲image.php

image.php 僞代碼

獲取的高度和寬度從文件名

調整大小並保存圖像的緩存文件夾

服務與內容型和ReadFile的圖像。

這樣我試圖減少HTTP請求和PHP加載與readfiles。 如果瀏覽器存在,則獲取圖像/ jpeg,如果不存在,則會生成該圖像。

最終所有圖像都將被緩存並以正確的高度和寬度進行投放,因此瀏覽器不會下載超大圖像。

唯一的解決方案..如果您將圖像url更改爲不同的尺寸,則可以填滿服務器。

我做得對嗎,正確的做法是什麼?有沒有機會阻止這種情況發生?

我知道這個緩存的整個概念已經提煉了一百萬次,請賜教。

回答

1

一些方法:

  • 維護允許分辨率的陣列,並檢查請求的分辨率是數組英寸缺點:無法快速添加分辨率而無需編輯陣列。

  • 如果這是在CMS上下文中:只允許通過身份驗證的用戶創建新的圖像(它們尚不在緩存中);否則拒絕請求。當經過身份驗證的用戶在CMS中添加圖像時,會預覽該圖像,然後執行此操作會生成調整大小的圖像。下行:並非完全易於實施。

+0

考慮到網絡商店的特殊情況,允許的分辨率陣列聽起來不錯。 –

+0

CMS的上下文是可能的,我通常使用CKeditor爲我的CMS,並且能夠編輯代碼,以便它指向文件,就像我想要的那樣。 –

+1

總的來說一些不錯的提示和想法,謝謝。 –

1

緩存是一個明顯不平凡的問題 - 您的解決方案似乎是合理的,但確實對有意和無意的拒絕服務攻擊開放。它也不能解決圖像變化時發生的情況 - 如何從緩存中刪除所有調整大小的圖像?它不設置緩存頭以允許「下游」緩存。它不涉及同時刷新整個緩存的風險,要求在HTTP請求的上下文中重新生成所有圖像,這可能是一個主要的性能漏洞。

你有沒有看了「現成的」解決方案,如Apache's caching module

+0

確實,重新生成緩存是第一次訪問時的主要性能損失。對於這種特殊情況,該網站在IIS上運行,我無權安裝模塊。但是對於我的其他項目,我一定會考慮到這一點。謝謝。 –

0

我只是做:

<img src="/thumbnail.php?thumb=mybigpicture.ext" ... /> 

這裏就是我如何做到這一點。請注意,此實現縮放圖像,不管它們是寬度還是高度,反之亦然,並且不像大多數PHP嘗試那樣進行縮放。

<?php 

function thumb_image($request = "") { 
    $cfgthumb['folder'] = "/images/cache"; 
    $cfgthumb['height'] = 150; 
    $cfgthumb['width'] = 200; 
    $cfgthumb['error'] = "/images/error.jpg"; 
    $cfgthumb['default'] = "/images/notfound.jpg"; 

    $thumb = $cfgthumb['folder'] . "/" . md5($request); 
    header("Content-Type: image/jpeg"); 
    if (is_readable($thumb)) echo file_get_contents($thumb); 
    elseif (is_readable($request)) { 
    $extension = strtolower(end(explode(".", $request))); 
    switch ($extension) { 
    case "gif": 
     $simage = imagecreatefromgif($request); 
     break; 
    case "jpeg": 
    case "jpg": 
     $simage = imagecreatefromjpeg($request); 
     break; 
    case "png": 
     $simage = imagecreatefrompng($request); 
     break; 
    } 
    if ($simage) { 
     $simage_width = imagesx($simage); 
     $simage_height = imagesy($simage); 
     if (($simage_width > $cfgthumb['width']) || ($simage_height > $cfgthumb['height'])) { 
     if ($simage_width > $simage_height) { 
      $dimage_width = $cfgthumb['width']; 
      $dimage_height = floor($simage_height * ($cfgthumb['width']/$simage_width)); 
     } else { 
      $dimage_width = floor($simage_width * ($cfgthumb['height']/$simage_height)); 
      $dimage_height = $cfgthumb['height']; 
     } 
     } else { 
     $dimage_width = $simage_width; 
     $dimage_height = $simage_height; 
     } 
     $dimage = imagecreatetruecolor($dimage_width, $dimage_height); 
     imagegammacorrect($simage, 2.2, 1.0); 
     imagecopyresampled($dimage, $simage, 0, 0, 0, 0, $dimage_width, $dimage_height, $simage_width, $simage_height); 
     imagegammacorrect($dimage, 1.0, 2.2); 
     imagejpeg($dimage, $thumb, 100); 
     imagejpeg($dimage, NULL, 100); 
     imagedestroy($simage); 
     imagedestroy($dimage); 
    } else echo file_get_contents($cfgthumb['error']); 
    } else echo file_get_contents($cfgthumb['default']); 
} 

?> 
+0

我已經有了這個代碼,除了我的動態維度加上我這樣做的方式我減少服務器負載,讓瀏覽器獲取圖像文件,而不是:服務器,然後瀏覽器。問題是我想要一種方法來防止人們填滿我的服務器。這可以通過@ Pekka允許的維數組來實現。 –

+0

對不起,如果這不能真正解決您的具體問題。我更喜歡讓PHP處理整個過程而不是使用mod_rewrite或類似的方法(即可以訪問磁盤上的靜態文件),原因有兩個:首先,您只需要打擾源圖像文件和縮略圖「照顧好自己「,其次,你不需要一次生成大量的縮略圖,因爲它們是按需生成的。 – dogglebones

+0

就像我說的PHP服務文件增加負載儘可能少。將訪問者直接指向圖像文件然後指向提供圖像的php文件會更快。另外,我解釋的一切都會按需生成。 「你只需要打擾源圖像文件」,你是什麼意思?我的方法也這樣做?我們的方法之間幾乎沒有什麼區別,除了我使用mod_rewrite取出用於服務文件的php步驟,並且僅在php不存在並且必須生成時用php提供文件,之後的時間將生成IMG。 –

2

不知道,如果我不回答爲時已晚,但你爲什麼不使用簡單SLIR (Smart Lencioni Image Resizer)是什麼?它可以執行任何你需要的操作(包括緩存和緩存管理),所以你可以簡單地將其放入並使用。

+0

感謝您的提示,我會牢記在心:) –

相關問題