如何在PHP中使用HTTPcaching头
我有一个PHP 5.1.0网站(实际上它是5.2.9,但它也必须运行在5.1.0以上)。
页面是dynamic生成的,但其中大部分都是静态的。 通过静态我的意思是内容不会改变,但内容周围的“模板”可以随着时间而改变。
我知道他们已经有几个caching系统和PHP框架,但我的主机没有安装APC或Memcached,我没有为这个特定的项目使用任何框架。
我想页面被caching(我认为默认PHP“禁止”caching)。 到目前为止,我正在使用:
session_cache_limiter('private'); //Aim at 'public' session_cache_expire(180); header("Content-type: $documentMimeType; charset=$documentCharset"); header('Vary: Accept'); header("Content-language: $currentLanguage");
我读了许多教程,但我找不到简单的东西(我知道caching是复杂的,但我只需要一些基本的东西)。
什么是“必须”有标题发送来帮助caching?
谢谢!
您可能希望使用private_no_expire
而不是private
,但为您知道不会更改的内容设置过期,并确保处理if-modified-since
和if-none-match
类似于Emil的post的请求。
$tsstring = gmdate('D, d MYH: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
可能是基于内容或用户标识,语言和时间戳的校验和,例如
$etag = md5($language . $timestamp);
您必须有一个Expires标题。 从技术上讲,还有其他的解决scheme,但Expires头部确实是最好的,因为它告诉浏览器在到期date和时间之前不要重新检查页面,只是从caching中提供内容。 它工作真的很棒!
检查来自浏览器的请求中的If-Modified-Since标头也是有用的。 如果浏览器的“caching”中的内容仍然是正确的版本,那么这个标题就会被发送。 如果您的页面从那时起没有被修改,只需发送一个HTTP 304代码(未修改)。 下面是一个发送一个304代码10分钟的例子:
<?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 ?>
为caching页面设置截止date是将其caching在客户端的一种有用方法。
拿你的select – 或者全部使用它们! 🙂
标题('Expires:Thu,01-Jan-70 00:00:01 GMT'); ('Last-Modified:'。gmdate('D,d MYH:i:s')。'GMT'); 头(“caching控制:无存储,无caching,必须重新validation”); ('Cache-Control:post-check = 0,pre-check = 0',false); 标题('Pragma:no-cache');
这是一个为你做httpcaching的小类。 它有一个名为“Init”的静态函数,它需要2个参数,上次修改页面(或浏览器请求的任何其他文件)的date的时间戳,以及该页面可以保存的最大时间由浏览器caching。
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 MYH: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); } }
我是做jsoncaching在服务器来自Facebook饲料什么都没有工作,直到我把刷新和隐藏错误报告。 我知道这个恶魔的代码,但希望快速修复尽快。
error_reporting(0); $headers = apache_request_headers(); //print_r($headers); $timestamp = time(); $tsstring = gmdate('D, d MYH: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
像魅力一样工作。