如何将 HTTP 缓存标头与 PHP 一起使用

2022-08-30 08:52:31

我有一个PHP 5.1.0网站(实际上它是5.2.9,但它也必须在5.1.0 +上运行)。

页面是动态生成的,但其中许多页面大多是静态的。通过静态,我的意思是内容不会改变,但围绕内容的“模板”会随着时间的推移而改变。

我知道它们已经是几个缓存系统和PHP框架,但我的主机没有安装APC或Memcached,我没有为这个特定的项目使用任何框架。

我希望页面被缓存(我认为默认情况下PHP“不允许”缓存)。到目前为止,我正在使用:

session_cache_limiter('private'); //Aim at 'public'
session_cache_expire(180);
header("Content-type: $documentMimeType; charset=$documentCharset");
header('Vary: Accept');
header("Content-language: $currentLanguage");

我读了很多教程,但我找不到简单的东西(我知道缓存很复杂,但我只需要一些基本的东西)。

什么是“必须”要发送的标头来帮助缓存?


答案 1

您可能希望使用 而不是 ,但为您知道不会更改的内容设置较长的过期时间,并确保处理和请求类似于Emil的帖子。private_no_expireprivateif-modified-sinceif-none-match

$tsstring = gmdate('D, d M Y H:i:s ', $timestamp) . 'GMT';
$etag = $language . $timestamp;

$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] : false;
if ((($if_none_match && $if_none_match == $etag) || (!$if_none_match)) &&
    ($if_modified_since && $if_modified_since == $tsstring))
{
    header('HTTP/1.1 304 Not Modified');
    exit();
}
else
{
    header("Last-Modified: $tsstring");
    header("ETag: \"{$etag}\"");
}

其中可以是基于内容或用户 ID、语言和时间戳的校验和,例如$etag

$etag = md5($language . $timestamp);

答案 2

您必须具有 Expires 标头。从技术上讲,还有其他解决方案,但是 Expires 标头确实是最好的解决方案,因为它告诉浏览器不要在过期日期和时间之前重新检查页面,而只是从缓存中提供内容。它的工作原理真的很棒!

在来自浏览器的请求中检查 If-Modified-From 标头也很有用。当浏览器“不确定”其缓存中的内容是否仍为正确版本时,将发送此标头。如果您的页面从那时起未被修改,只需发回HTTP 304代码(未修改)即可。下面是一个发送 304 代码十分钟的示例:

<?php
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
  if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < time() - 600) {
    header('HTTP/1.1 304 Not Modified');
    exit;
  }
}
?>

您可以将此检查放在代码的早期,以节省服务器资源。


推荐