处理 PHP 脚本中的 If-modified-since 标头

2024-03-19

我有一个 PHP 脚本,用?img=范围。

该参数的值是图像的(urlencoded)URL。

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

如果没有 - 它会下载它。之后,它可以选择调整图像大小并将其发送到 STDOUT,即返回到请求浏览器,前面加上内容类型 and 上一次更改标题:

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

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

不过我想添加功能来处理传入的如果-修改-自header - 发送未修改304回复。

我的问题是:

1)当在 Apache 中运行时,这在 PHP 中是否可能?

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

奖金问题)如何添加内容长度调整大小的图像的标题?

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

<?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 中绝对是可能的!

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

要解码日期/时间值(我相信使用 rfc822 编码),您可以使用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”标头并停止。

否则,脚本将按正常方式继续。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

处理 PHP 脚本中的 If-modified-since 标头 的相关文章

随机推荐

  • C Master Volume Windows 中的 __uuidof

    我想用 C 改变主音量 但是 uuidof仅适用于 C 我可以用什么来代替它 const CLSID CLSID MMDeviceEnumerator uuidof MMDeviceEnumerator const IID IID IMMD
  • 在JavaScript中使用bind来避免闭包是否正确?

    闭包对于浏览器的内存来说是否太糟糕了 在 JavaScript 中使用 bind 避免闭包是一个好方法吗 现有代码 var oControl new Control var self this click function e closur
  • 我正在尝试使用 Firebase 在 Flutter 中使用 google 注销,但它不起作用

    我将 Flutter 与 Firebase 结合使用 当我尝试使用电子邮件和密码注销时 效果很好 但当我尝试使用谷歌时 它不起作用 这是我的代码 try switch user providerData 0 providerId case
  • IIS7 集成与经典管道 - 哪个使用更多 ASP.NET 线程?

    通过集成管道 所有请求都通过 ASP NET 传递 包括图像 CSS 而在经典管道中 默认情况下仅通过 ASP NET 传递对 ASPX 页面的请求 集成管道会对线程使用产生负面影响吗 假设我从 IIS 服务器请求 500 MB 二进制文件
  • Eclipse Oxygen 的 Lombok 问题

    我最近升级到了新的 Eclipse 版本 Oxygen 我从网站下载了 lombok jar 并安装了它 这就是如何eclipse ini安装后的样子 startup plugins org eclipse equinox launcher
  • Android Volley Https SSL 自签名和 Google Maps API

    我们正在使用 Android Volley 并使用可以正常工作的自认证 SSL 但现在我们想要实现 Google 地图 但它不起作用 它只是不会抛出任何错误 它只是显示一个灰色的屏幕 This is our implementation o
  • Shell脚本:在不排序的情况下查找整数序列中的最大值

    我有一个包含一长串整数的文件 10 4 66 我想使用 UNIX 命令行工具找到最大值 我知道我可以使用sort 事实上 这个问题有解决方案 使用sort 但是效率很低 需要 O N log N 和大量内存 通过一个简单的 for 循环 我
  • 为什么我的故事板中的视图控制器不断消失?

    我的故事板文件中的视图控制器不断消失 截至目前 我必须按向上箭头并突出显示每个项目才能恢复我的视图控制器 我可以做些什么来摆脱这个问题 还有什么我可以做的来将这些消失的视图控制器恢复到我的故事板上 这是一个错误 通常我可以通过关闭故事板并重
  • jquery只获取所有带有id的html元素

    我有一个 div 其中有很多 html 元素 如其他 div trs tds 表格等 是否可以获取所有具有 id 的元素 我知道问 test 会给我这个 id 的特定元素 但有可能得到find 或者类似的东西 id 返回所有设置了 id 的
  • WOW.js + 查询加载器 2

    我有一个问题WOW js https github com matthieua WOW and 查询加载器2 http gayadesign com diy queryloader2 preload your images with eas
  • vcruntime140.dll 与 vcruntime140d.dll

    这两个dll有什么区别vcruntime140 dll and vcruntime140d dll 为什么我们需要它们 它们都是 Microsoft Visual C 2015 Redistributable 的一部分吗 谷歌搜索了很长一段
  • 无论我做什么,NSLayoutManager 都会隐藏新行字符

    我正在尝试显示不可见的字符 例如 NSTextView 子类中的换行符 像重写 NSLayoutManager 的 drawGlyph 方法这样的常用方法是一个坏主意 因为它太慢并且无法在多页布局中正常工作 我想做的是重写 NSLayout
  • 如何监控客户端与 WCF 服务的连接?

    我创建了一个 WCF 服务 其中 ServiceHost 类无法实例化为单例 我需要监视与该服务的每个连接 甚至在第一次调用与其关联的方法之前也是如此 在实践中 我想记录客户端何时打开与服务通信的通道 是否可以 在网上我找到的解决方案只有两
  • 从字符串中删除第一个字符

    有没有办法删除或替换为 the X 从词的开头 Ex XN5634 erX123 erNX45 期望的输出 N5634 er123 erNX45 我总共有大约14000字 我用了 gsub X mylist fixed T but X被移除
  • 加载 CharSequence 时出错(scala 2.11.4)

    他们建议我更新 scala 所以我这样做了 scala version Scala code runner version 2 11 4 Copyright 2002 2013 LAMP EPFL 但这个错误仍然存 在 my project
  • 如何更改选项菜单的背景颜色?

    我正在尝试更改选项菜单的默认颜色为白色 我希望选项菜单上的每个项目都有黑色背景 我已经在菜单元素内的项目元素上尝试了一些像 android itemBackground 000000 的拍摄 但它不起作用 我怎样才能做到这一点 在花费了大量
  • window.location.href 与 React-router-dom 的重定向实用程序

    我有使用 React 和 React Router 编写的 webapp 使用 window location href 进行重定向与使用通过 React router 提供的组件有什么优点 缺点 Use history push page
  • 如何使用Python向Firebase中的用户发送电子邮件验证码?

    我正在做一个KivyMD应用程序和我想在用户注册应用程序时发送电子邮件验证码 我正在使用一个firestore数据库与python对于这个项目 但我没有这样做的想法 注册流程是 用户使用他的电子邮件地址注册该应用程序 电子邮件包含一个代码
  • 编辑/保存 CSV 文件中的行

    遵循此操作后topic https stackoverflow com questions 13100139 update one column in csv file c sharp我能够创造 新行 但我的问题是怎么做 我将新行保存或写入
  • 处理 PHP 脚本中的 If-modified-since 标头

    我有一个 PHP 脚本 用 img 范围 该参数的值是图像的 urlencoded URL 我的脚本检查该图像是否已存储在我的服务器上 如果没有 它会下载它 之后 它可以选择调整图像大小并将其发送到 STDOUT 即返回到请求浏览器 前面加