【问题标题】:using HTTP headers for cache control in PHP在 PHP 中使用 HTTP 标头进行缓存控制
【发布时间】:2011-11-22 14:44:47
【问题描述】:

如何使用 HTTP 标头来控制何时更新我的​​缓存?

目前我正在使用 cURL 来获取实时 XML 提要,然后将其保存到 xml 文件中。 Feed 还会发送 HTTP 标头,通知您何时更新。更新时间可以在 30 秒到 3 分钟之间。

标题是这样的

Expires: Mon, 22 Nov 2011 10:01:22 GMT

这是我目前使用的每 30 秒检查一次

if (file_exists($filename) && (filemtime($filename) > time() - 30)) {

我希望它只根据 HTTP 标头所说的内容进行更新。

我该怎么做呢?

还有没有更好的方法来缓存这个 XML 提要而不是将其保存到 XML 文件中?

【问题讨论】:

    标签: php caching http-headers browser-cache cache-control


    【解决方案1】:

    首先你必须解析标题中给出的日期:

    $header = "Expires: Mon, 22 Nov 2011 10:01:22 GMT";
    preg_match(
        "/Expires: [A-Za-z]+, ([0-9]{1,2}) ([A-Za-z]+) ([0-9]{4}) ([0-9:]+) ([A-Z]{3})/", 
        $header,
        $matches
    );
    $months = array(
        "Jan" => "01",
        "Feb" => "02", 
        "Mar" => "03",
        "Apr" => "04",
        "May" => "05",
        "Jun" => "06",
        "Jul" => "07",
        "Aug" => "08",
        "Sep" => "09",
        "Oct" => "10",
        "Nov" => "11",
        "Dec" => "12"
    );
    $day = $matches[1];
    $month = $months[$matches[2]];
    $year = $matches[3];
    $time = $matches[4];
    $zone = $matches[5];
    
    $date = new DateTime("$year-$month-$day $time", new DateTimeZone($zone));
    

    然后您可以根据实际时间检查这一点,并且仅在达到上次更新的 $date 时才执行更新

    $now = new DateTime();
    if($now > $date);
    

    您应该在下载 XML 并解析日期后将 $date 保存在文件或数据库中。 下次执行脚本时,只需对照新的 DateTime() 检查保存的日期,看看是否已经更新它,如果没有,您可以从文件中加载保存的 XML。

    将 XML 保存为文件很好,您可以将其保存到数据库中,但我不会只为保存一个 XML 结构而设置数据库。如果您想保留旧 XML 的历史记录,那么 DB 再次有意义。

    【讨论】:

    • 请注意,这将使用正确提供的时区。
    • 好的,但是我如何只获取 Expires: Mon, 22 Nov 2011 10:01:22 GMT 而不是所有的标题?
    • 只需放入完整的标题,正则表达式应该与过期内容匹配...
    • 刚刚有时间测试它,我遇到了一个致命错误。 atal 错误:未捕获的异常 'Exception' 带有消息 'DateTime::__construct() [datetime.--construct]:依赖系统的时区设置。您必须使用 date.timezone 设置或 date_default_timezone_set() 函数。如果您使用了这些方法中的任何一种,但仍然收到此警告,您很可能拼错了时区标识符。我们选择了 'America/Los_Angeles' 代替 'PST/-8.0/no DST'
    • 您可以设置 $now = new DateTime("now",new DateTimeZone("GMT")); 并将 GMT 替换为您当地的时区,例如德国的 Europe/BerlinUTC 或其他的...
    【解决方案2】:

    Expires 标头告诉您文档到期的时间 ​​- 即“在此日期之前不要检查”。请注意,它指定了时区 (GMT),因此这可能不是您的当地时间。

    【讨论】:

    • 来自ietf.org/rfc/rfc2109.txt,应该是GMT+0,所以很容易调整到服务器时区
    • @Esailija:好点——强调“应该”; 99% 的服务器将遵循 RFC;有些只是不会。至于 GMT+0,这不是什么大问题,例如对于 GMT-5 中的某个人,因为差异大到足以显而易见,但作为 GMT+1 中的某个人,没有意识到偏移量至少咬了我一次。
    猜你喜欢
    • 1970-01-01
    • 2017-06-01
    • 2013-04-01
    • 2012-08-26
    • 1970-01-01
    • 2021-11-29
    • 2023-04-08
    • 2011-09-21
    • 2011-09-14
    相关资源
    最近更新 更多