我的网站上有很多图像,当我们请求在托管服务器上保存磁盘空间时,它们会从图像服务器拉到主服务器上。
为了实现这一点,我在.htaccess
文件中有一个条目,基本上将人们从/images/image.jpg
内部重定向到download.php
,检查文件是否存在。如果文件存在则会提供它(下面的代码),否则它将使用CURL
拉入远程文件,然后重定向到自己header("Location: ".$_SERVER['REQUEST_URI']);
,然后显示图像。
以这种方式向浏览器提供图像效率低下吗?让Web服务器自然地执行它会更快吗?阅读和显示文件的代码如下。
$file_extension = strtolower(substr(strrchr($filename,"."),1));
header("Pragma: public");
header("Content-Type: image/jpg");
header("Content-length: ".filesize($filename));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");
我会变得更好(阅读:效率更高)不使用htaccess重定向但实际修改我的404页面以检查特定于图像的404,然后下载它们?
以下.htaccess
定义了重定向到download.php
^images/([0-9]+)_([a-z0-9_]+).jpg$ /download.php?id=$1
答案 0 :(得分:3)
有点不清楚你的意思是'重定向到自己'。有没有理由你的download.php不能使用CURL从远程服务器获取图像,然后以相同的方式使用你的代码示例提供它?为什么需要重定向?
如果可以避免,最好不要使用PHP引擎来提供图像,因为Apache可以自己更有效地完成这项工作。你也失去了一些Apache的默认行为,例如:您的代码示例不是发送最后修改的标头或处理etags,因此如果用户重新访问同一页面,他们将最终再次下载图像而不是使用缓存版本。
您建议的替代方法会更好一些,因为一旦您的脚本第一次下载图像,所有后续请求将由Apache直接提供。只需确保您没有随图像一起发送404标题。
或者可以使用htaccess检查文件是否存在,因此您只能将对不存在的图像的请求重定向到download.php,而不必修改您的404脚本。像这样(未经测试):
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/images
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^.*$ download.php [NC,L]
这意味着:如果REQUEST_URI以/ images开头,并且文件名与文件系统上的现有文件不匹配,请将其重写为download.php。
我还建议查看X-Sendfile,一个Apache模块,它可以很容易地提供图像(和其他二进制数据)。在PHP中使用它就像发送包含文件路径的头一样简单:
header("X-Sendfile: /home/whatever/public/images/something.jpg");
然后,Apache为您完成所有其他工作 - 读取并输出文件内容并发送所有适当的标头。默认情况下通常不启用该模块,因此您可能需要安装它或与主机核实。
答案 1 :(得分:1)
你最好只用重写前缀:
RewriteCOnd %{REQUEST_FILENAME} !-f
...如果你在download.php中下载文件,为什么不向用户显示呢?无需重定向。
答案 2 :(得分:0)
我认为直接提供图像总是比你不能使用浏览器缓存的代码更快,但我不确定。
答案 3 :(得分:0)
就客户端到浏览器的连接而言,它与正常提供数据的速度完全一样快。 Apache并不关心信息来自何处,它只是发送它所传递的数据。如果数据是读取文件的结果或1000万像C ++程序的结果,那么它只是位。
你的方法较慢的地方是它从图像服务器中提取图像。这实质上意味着图像被发送两次。一旦从图像服务器 - >主机服务器,然后再从主机服务器 - >客户。如果您的映像服务器和主机服务器位于相同的局域网中,节点相对较少且连接速度非常快,那么这可能不是一个明显的区别。如果图像服务器位于不同的网络上,或者图像文件非常大,则差异可能很大,并且可能不值得花费磁盘空间。