在PHP脚本中处理If-modified-since标头 [英] Handling If-modified-since header in a PHP-script

查看:161
本文介绍了在PHP脚本中处理If-modified-since标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个PHP脚本,该脚本使用?img = 参数调用.

I have a PHP script which is called with an ?img= parameter.

该参数的值是图像的(加编码的)URL.

The value for that parameter is an (urlencoded) URL of an image.

我的脚本检查该图像是否已经存储在我的服务器上.

My script checks, if that image is already stored at my server.

如果不是,则将其下载.之后,它可以选择调整图像的大小并将其发送到STDOUT,即返回到请求的浏览器,并带有 Content-Type Last-modified 标头:

If not - it downloads it. After that it optionally resizes the image and sends it to STDOUT, i.e. back to the requesting browser, prepended with Content-Type and Last-modified headers:

Connection:close
Content-Type:image/jpeg
Date:Fri, 01 Jun 2012 08:28:30 GMT
Last-Modified:Fri, 01 Jun 2012 08:02:44 GMT
Server:Apache/2.2.15 (CentOS)
Transfer-Encoding:chunked
X-Powered-By:PHP/5.3.3

这是解决一些跨域问题所必需的,并且自一年以来对我来说很有效:

This is needed to workaround some crossdomain issues and works well for me since over a year:

不过,我想添加一些功能来处理传入的 If-Modified-since 标头-发送 Not Modified 304 响应.

However I'd like to add functionality to handle the incoming If-Modified-since header - to send a Not Modified 304 response.

我的问题是:

1)在Apache中运行时,在PHP中甚至可以实现吗?

1) Is that even possible in PHP, when run in Apache?

2)如何在此处最好地处理(即解析和产生)PHP中的日期?

2) How to handle (i.e. parse and produce) the dates best in PHP here?

奖金问题)如何为调整大小后的图像添加 Content-Length 标头?

Bonus question) How to add a Content-Length header for the resized images?

下面是我的代码(我省略了CURL下载部分):

My code is below (I've omitted the CURL-downloading part):

<?php

define('CACHE_DIR', '/var/www/cached_avatars/');

$img    = urldecode($_GET['img']);
$cached = CACHE_DIR . md5($img);

# omitted downloading part for brevity

$readfh = fopen($cached, 'rb');
if ($readfh) {
        flock($readfh, LOCK_SH);

        $size = getimagesize($cached);
        $w    = $size[0];
        $h    = $size[1];
        $type = $size[2];
        $mime = $size['mime'];

        # find the downscale factor to fit image into $maxw x $maxh
        $scale = max($w / $maxw, $h / $maxh);

        header('Content-Type: ' . $size['mime']);
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', filemtime($cached)));

        $length = filesize($cached);
        $buf = fread($readfh, $length);
        fclose($readfh);

        # the image is smaller than $maxw x $maxh, do not scale up
        if ($scale <= 1) {
                header('Content-Length: ' . $length);
                print($buf);
                return;
        }

        $tw = $w / $scale;
        $th = $h / $scale;
        $image = imagecreatefromstring($buf);
        $thumb = imagecreatetruecolor($tw, $th);
        imagecopyresampled($thumb, $image, 0, 0, 0, 0, $tw, $th, $w, $h);
        imagedestroy($image);

        # How to add Content-Length here, after image resizing?

        if (IMAGETYPE_JPEG == $type)
                imagejpeg($thumb, null, 75);
        else if (IMAGETYPE_PNG == $type)
                imagepng($thumb, null, 9);
        else if (IMAGETYPE_GIF == $type)
                imagegif($thumb, null);

        imagedestroy($thumb);
}

?>

推荐答案

在PHP中这绝对是可能的!

This is definitely possible in PHP!

当浏览器检查是否有修改时,它将发送If-Modified-Since标头;在PHP中,此值将在$_SERVER['HTTP_IF_MODIFIED_SINCE']中设置.

When the browser checks if there were modifications, it sends an If-Modified-Since header; in PHP this value would be set inside $_SERVER['HTTP_IF_MODIFIED_SINCE'].

要解码日期/时间值(我相信使用rfc822进行编码),您可以使用strtotime(),因此:

To decode the date/time value (encoded using rfc822 I believe), you can just use strtotime(), so:

if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && 
    strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($localFileName))
{
    header('HTTP/1.0 304 Not Modified');
    exit;
}

说明:如果If-Modified-Since标头是由浏览器发送的,并且日期/时间至少是您正在提供的文件的修改日期,则编写"304 Not Modified"标头并停止.

Explanation: if the If-Modified-Since header is sent by the browser AND the date/time is at least the modified date of the file you're serving, you write the "304 Not Modified" header and stop.

否则,脚本会照常继续.

Otherwise, the script continues as per normal.

这篇关于在PHP脚本中处理If-modified-since标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆