2

好的,所以我对如何提供和缓存我的图像有了一个想法。我不知道这是否是正确的做法,但如果是,我想知道如何防止滥用。

情况:

索引.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 伪代码

从文件名获取高度和宽度

调整图像大小并将图像保存到缓存文件夹

使用 content-type 和 readfile 提供图像。

通过这种方式,我试图通过 readfiles 减少 HTTP 请求和 PHP 负载。如果存在,浏览器将获取图像/jpeg,否则将生成。

最终,所有图像都将被缓存并以正确的高度和宽度提供服务,因此浏览器不会下载过大的图像。

唯一的问题..如果您将图像网址更改为不同的尺寸,您可以填满服务器。

我做得对吗,正确的方法是什么。有没有机会阻止这种情况发生?

我知道缓存的整个概念已经被提炼了一百万次,请赐教。

4

4 回答 4

2

不确定我的答案是否为时已晚,但你为什么不简单地使用SLIR(Smart Lencioni Image Resizer)呢?它可以做任何您需要的事情(包括缓存和缓存管理),因此您只需将其放入并使用。

于 2012-08-02T05:50:12.177 回答
1

一些方法:

  • 维护一个允许分辨率的数组,并检查请求的分辨率是否在该数组中。缺点:您无法在不编辑数组的情况下快速添加分辨率。

  • 如果这是在 CMS 上下文中:仅允许经过身份验证的用户创建图像(尚未在缓存中);否则拒绝该请求。当经过身份验证的用户在 CMS 中添加图像时,他们会预览它,然后生成调整大小的图像。缺点:并不完全容易实现。

于 2012-06-23T11:23:02.043 回答
1

缓存显然是一个重要的问题 - 您的解决方案似乎合理,但确实容易受到有意和无意的拒绝服务攻击。它也没有解决图像更改时会发生什么 - 如何从缓存中删除所有调整大小的图像?它没有设置缓存标头以允许“下游”缓存。它没有处理同时刷新整个缓存的风险,需要在 HTTP 请求的上下文中重新生成所有图像,这可能是主要的性能消耗。

您是否看过诸如Apache 的缓存模块之类的“现成”解决方案?

于 2012-06-23T11:24:55.350 回答
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']);
}

?>
于 2012-06-23T11:49:55.247 回答