PHP:在Webroot和缓存之外流式传输图像

时间:2012-03-23 19:21:13

标签: php caching

我正在使用Apache,当我第一次直接请求图像时,图像的状态为“200 OK”。后续请求的状态为“304 Not Modified”,这很好,因为它为客户端和服务器节省了带宽。

我正在开发一个允许用户上传图片的网站。这些图像需要存储在webroot之外,不仅是为了防止热链接,而且还可以收集图像的统计信息。所以我的想法是使用这样的PHP脚本来传输图像:

<?php

    $image_to_stream = '/path/outside/of/webroot/image.jpg';
    $cache_seconds = 2592000; // 30 days

    header("Cache-Control: max-age=$cache_seconds");
    header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $cache_seconds) . ' GMT');
    header('Pragma: cache');
    header('Content-Type: image/jpg');
    header('Content-length: ' . filesize($image_to_stream));

    readfile($image_to_stream);

?>

但是,脚本似乎始终具有“200 OK”状态,并且整个图像都会进行流式处理。有没有办法解决这个问题,还是我应该采取其他方法或什么?谢谢!

1 个答案:

答案 0 :(得分:0)

您需要处理If-Modified-Since请求标头。

基本上,在本地检查该文件的时间戳。如果自If-Modified-Since标题中指定的日期以来已更改,请将其返回。否则,发送bac,304未修改。

来自RFC:

  

具有If-Modified-Since标头且没有Range标头的GET方法请求仅在自If-Modified-Since标头给定的日期以来已修改标识的实体时才传输标识的实体。确定这一点的算法包括以下情况:

     

a)如果请求通常会产生除a之外的任何其他内容            200(OK)状态,或者传递的If-Modified-Since日期是            无效,响应与普通GET完全相同。            比服务器当前时间晚的日期是            无效。

     

b)如果自If-Modified-Since以来修改了变体            日期,响应与正常GET完全相同。

     

c)如果因为有效的If-而未修改变体            修改 - 从日期开始,服务器应该返回304(不是            修改后的反应。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

您可以使用此PHP代码发送:

header('HTTP/1.1 304 Not Modified', true, 304);