调用缓存图像时哪个更高效/更快?
Posted
技术标签:
【中文标题】调用缓存图像时哪个更高效/更快?【英文标题】:Which is more efficient/faster when calling a cached image? 【发布时间】:2010-05-13 15:44:23 【问题描述】:我在 php 中制作了一个图像缩放器。调整图像大小时,它会缓存具有新尺寸的新 jpg 文件。下次您调用确切的 img.php?file=hello.jpg&size=400 时,它会检查是否已经创建了新的 jpg。
-
如果尚未创建,它会创建文件,然后打印输出(酷)。
如果它已经存在,则不需要生成新文件,而是调用已缓存的文件。
我的问题是关于第二种情况。哪个更快?
-
重定向:
header('Location: cache/hello_400.jpg');die();
抓取数据并打印缓存文件:$data = file_get_contents('cache/hello_400.jpg'); header('Content-type: '.$mime);
header('Content-Length: '.strlen($data));
echo $data;
还有其他方法可以改善吗?
如果有人想要生成的代码,请查看: http://egobits.com/misc/img.phps
感谢大家的帮助!
【问题讨论】:
一个好问题(我不确定哪个更快)。 【参考方案1】:我会选择从不将数据打印到浏览器。这两种情况都应该永久重定向到生成的图像。除非图像尚不存在,否则会在发送 Location 标头之前创建。
编辑:
为了清楚我所说的永久重定向是什么意思...
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://path/to/image');
【讨论】:
添加到Matt,它可以缓存从浏览器到代理服务器的互联网点的图像。【参考方案2】:也许您可以执行以下操作:
-
为这些图像设置一些目录。
链接到此目录中的图片 (
<a href="/img/resizable/hello_400.jpg>
)。
如果图像尚不存在,请将您的网络服务器设置为重定向到您的 php 脚本。如果你在 Apache 上,一个简单的 .htaccess 就可以了。在 PHP 中,您可以使用 $_SERVER["REQUEST_URI"]
来判断应该调整哪个图像的大小。
您的脚本保存并回显图像(但仅在第一次调用)。
这样,你会得到一些好处:
图像与任何其他静态文件一样被缓存(在代理或浏览器中)。 不必为每个请求调用 PHP 来重定向或输出静态数据。 您将If-modified-since
和其他与缓存相关的标头的实现留给网络服务器。
而且链接看起来更好:-)
/img/resizable 文件夹中的示例 .htaccess:
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule .* /img.php [L]
【讨论】:
+1 我同意。尽量委托给Apache,真正需要的时候才调用PHP。【参考方案3】:还有其他方法可以改善吗?
是的。
有一种方法只发送一个 HTTP 标头:条件获取。 你可以看看类似的脚本,http://shiftingpixel.com/2008/03/03/smart-image-resizer/,用于实现
【讨论】:
这非常有效。如果图像不存在,脚本会创建新调整大小的 img 并将其缓存。下次您请求相同的链接时,该脚本会为浏览器缓存的 img 提供服务。谢谢。 如果有人想要生成的代码,请查看:egobits.com/misc/img.phps 您可能需要考虑使用 readfile() 而不是 file_get_content 因为整个文件永远不会加载到 php 中并直接发送给用户 @ChrisT file_get_contents() 是将文件内容读入字符串的首选方法,所以我猜 readfile 不是最好的方法。 他不需要将其加载到字符串中,只需将其输出到浏览器即可【参考方案4】:作为第三种(更强大的)选项:将图像缓存在数据库中的二进制字段中,并在数据库中查询它。
实施所有三个解决方案并对其进行基准测试。
我猜第一个选项(重定向)将是现实世界中最慢的,因为它需要与第二个选项(file_get_contents)一样多的努力,但涉及第二个请求和更多开销。
【讨论】:
【参考方案5】:如果可能的话,你还可以实现一个函数来直接在你的 html 中设置缓存图像的 url,如:
<img src="<?php getImageUrl('hello.jpg', 400); ?>" />
getImageUrl() 将返回缓存图像的 url(如果存在),否则它将返回 url 以动态生成调整大小的图像。
【讨论】:
以上是关于调用缓存图像时哪个更高效/更快?的主要内容,如果未能解决你的问题,请参考以下文章
C#/.Net 使用QuestPDF操作生成PDF更快更高效!