2010-10-07 22 views
1

我的网站上有很多图像,当它们被请求保存我的托管服务器上的磁盘空间时,它们从图像服务器拉到主服务器上。如果图像不存在,自动重定向/下载 - 优化

要做到这一点我在01​​文件中的条目,基本上内部重定向人从/images/image.jpgdownload.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的,然后将它们下载?

这里是定义重定向到download.php

^images/([0-9]+)_([a-z0-9_]+).jpg$ /download.php?id=$1 

回答

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与/图像开始,文件名不符合文件系统上的现有文件,重写它的download.php。

我还建议寻找X-Sendfile,一个Apache模块,这使得它非常容易提供图像(和其他二进制数据)。在PHP中使用它是作为发送包含该文件的路径头一样简单:

header("X-Sendfile: /home/whatever/public/images/something.jpg"); 

阿帕奇然后为你做的所有工作休息 - 阅读和输出文件的内容和发送所有适当的头。该模块默认情况下通常不启用,因此您可能需要安装它或与您的主机进行核对。

+0

在.htaccess中检查文件存在是一个非常好的主意,关于从哪里开始的想法?什么是X-SendFile? – Chris 2010-10-07 18:15:00

+0

我试图使用X-Sendfile(这看起来很棒btw!)但它没有工作lol – Chris 2010-10-07 18:22:02

+0

我编辑了我的答案与htaccess示例和X-Sendfile的解释。如果您对X-Sendfile有任何问题,请检查phpinfo()以确保它已启用,并检查Apache错误日志是否仍然无效。 – 2010-10-07 18:31:31

0

我觉得发球直接图像将永远是比你的代码,不会让使用浏览器缓存,但我不知道快.htaccess

+0

就浏览器而言,一旦加载图像不会改变,因为它的文件大小和文件名没有改变。至少浏览器似乎缓存它! – Chris 2010-10-07 18:07:46

+0

是的,但图像加载通过一个PHP文件,所以我不知道它是否工作? – MatTheCat 2010-10-07 18:10:11

0

就客户端到浏览器的连接而言,它与通常的数据服务一样快。 Apache不关心信息来自哪里,它只是发送它交给的数据。如果数据是读取文件或像C++程序这样的一千万个结果的结果,那么这只是一点点。

你的方法比较慢的地方是从图像服务器上拉出图像。这基本上意味着图像被发送两次。一次从映像服务器 - >主机服务器,然后再从主机服务器 - >客户机。如果您的图像服务器和主机服务器位于同一局域网上,节点相对较少,连接速度非常快,那么这可能不会有明显的差异。如果图像服务器位于不同的网络上,或者图像文件非常大,则差异可能会很大,并且可能不值得花费磁盘空间。

1

你会与刚用前缀你重写更好:

RewriteCOnd %{REQUEST_FILENAME} !-f 

...如果你下载的文件中的download.php,为什么不直接展示给用户?不需要重定向。

+0

我原本是这么做的,但认为这样做会更快?此外,具体的RewriteCond做什么?我将如何将它纳入我的htaccess? (病毒更新问题) – Chris 2010-10-07 18:20:11

+0

如果文件不存在,它只会重定向到你的download.php文件。 – Wrikken 2010-10-07 18:38:15