好的,所以我对如何服务和缓存我的图像有一个想法。我不知道这是否是正确的方法,但如果是,我想知道如何防止滥用。
情况:
索引.php
<img src="images/cache/200x150-picture_001.jpg" />
images/cache/.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ images/image.php?f=$1 [L]
上面检查图像是否存在,如果不存在,它将被重写为图像.php
图片.php伪代码
从文件名获取高度和宽度
调整大小并将其保存到缓存文件夹
使用内容类型和读取文件提供图像。
通过这种方式,我正在尝试减少 HTTP 请求和 PHP 加载与读取文件。浏览器获取图像/jpeg(如果存在),如果不存在,则会生成图像/jpeg。
最终,所有图像都将被缓存并以正确的高度和宽度提供,因此浏览器不会下载超大的图像。
唯一的问题是,如果将图像URL更改为不同的尺寸,则可以填满服务器。
我做得对吗,正确的方法是什么。有没有机会阻止这种情况发生?
我知道缓存的整个概念已经被完善了一百万次,请启发我。
不确定我是否对答案还不算太晚,但你为什么不简单地使用 SLIR(智能 Lencioni 图像缩放器)呢?它可以做你需要的任何事情(包括缓存和缓存管理),所以你只需把它放进去使用。
一些方法:
-
维护允许的分辨率数组,并检查请求的分辨率是否在该数组中。缺点:如果不编辑数组,就无法快速添加分辨率。
-
如果这是在CMS上下文中:仅允许经过身份验证的用户创建新映像(尚未在缓存中);否则拒绝请求。当经过身份验证的用户在 CMS 中添加图像时,他们会预览它,并生成调整大小的图像。缺点:不完全容易实现。
缓存是一个明显不平凡的问题 - 您的解决方案似乎是合理的,但确实容易受到有意和无意的拒绝服务攻击。它也没有解决图像更改时会发生什么 - 如何从缓存中删除所有调整大小的图像?它不会将缓存标头设置为允许"下游"缓存。它不处理同时刷新整个缓存的风险,需要在HTTP请求的上下文中重新生成所有图像,这可能是一个主要的性能消耗。
您是否看过"现成"的解决方案,例如 Apache 的缓存模块?
我只是做:
<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']);
}
?>