[英]How to use HTTP cache headers with PHP
我有一个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");
我读了很多教程,但是我找不到简单的东西(我知道缓存是复杂的,但我只需要一些基本的东西)。
什么是“必须”有标题发送来帮助缓存?
您可能希望使用private_no_expire
而不是private
,但为您知道不会更改的内容设置较长的过期时间,并确保处理类似于Emil的帖子的if-modified-since
和if-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}\"");
}
其中$etag
可以是基于内容或用户ID,语言和时间戳的校验和,例如
$etag = md5($language . $timestamp);
您必须有一个Expires标头。 从技术上讲,还有其他解决方案,但Expires标头实际上是最好的,因为它告诉浏览器在到期日期和时间之前不重新检查页面,只是从缓存中提供内容。 它真的很棒!
在浏览器的请求中检查If-Modified-Since标头也很有用。 当浏览器“不确定”时,如果其缓存中的内容仍然是正确的版本,则会发送此标头。 如果您的页面从那时起未被修改,则只需发回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;
}
}
?>
您可以在代码中尽早进行此检查以节省服务器资源。
<?php
header("Expires: Sat, 26 Jul 2020 05:00:00 GMT"); // Date in the future
?>
设置缓存页面的截止日期是在客户端缓存它的一种有用方法。
这是一个为您提供http缓存的小类。 它有一个名为'Init'的静态函数,需要2个参数,上次修改页面(或浏览器请求的任何其他文件)的日期的时间戳,以及此页面可以保存的最大年龄(以秒为单位)通过浏览器缓存。
class HttpCache
{
public static function Init($lastModifiedTimestamp, $maxAge)
{
if (self::IsModifiedSince($lastModifiedTimestamp))
{
self::SetLastModifiedHeader($lastModifiedTimestamp, $maxAge);
}
else
{
self::SetNotModifiedHeader($maxAge);
}
}
private static function IsModifiedSince($lastModifiedTimestamp)
{
$allHeaders = getallheaders();
if (array_key_exists("If-Modified-Since", $allHeaders))
{
$gmtSinceDate = $allHeaders["If-Modified-Since"];
$sinceTimestamp = strtotime($gmtSinceDate);
// Can the browser get it from the cache?
if ($sinceTimestamp != false && $lastModifiedTimestamp <= $sinceTimestamp)
{
return false;
}
}
return true;
}
private static function SetNotModifiedHeader($maxAge)
{
// Set headers
header("HTTP/1.1 304 Not Modified", true);
header("Cache-Control: public, max-age=$maxAge", true);
die();
}
private static function SetLastModifiedHeader($lastModifiedTimestamp, $maxAge)
{
// Fetching the last modified time of the XML file
$date = gmdate("D, j M Y H:i:s", $lastModifiedTimestamp)." GMT";
// Set headers
header("HTTP/1.1 200 OK", true);
header("Cache-Control: public, max-age=$maxAge", true);
header("Last-Modified: $date", true);
}
}
随你挑 - 或全部使用! :-)
header('Expires: Thu, 01-Jan-70 00:00:01 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache');
我在服务器上进行JSON缓存来自Facebook提供什么都没有工作,直到我把flush和hid错误报告。 我知道这不是理想的代码,但需要快速修复。
error_reporting(0);
$headers = apache_request_headers();
//print_r($headers);
$timestamp = time();
$tsstring = gmdate('D, d M Y H:i:s ', $timestamp) . 'GMT';
$etag = md5($timestamp);
header("Last-Modified: $tsstring");
header("ETag: \"{$etag}\"");
header('Expires: Thu, 01-Jan-70 00:00:01 GMT');
if(isset($headers['If-Modified-Since'])) {
//echo 'set modified header';
if(intval(time()) - intval(strtotime($headers['IF-MODIFIED-SINCE'])) < 300) {
header('HTTP/1.1 304 Not Modified');
exit();
}
}
flush();
//JSON OP HERE
这非常有效。
这是php缓存的最佳解决方案只需在脚本的顶部使用它
$seconds_to_cache = 3600;
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.