Created
October 5, 2012 15:00
-
-
Save nikcorg/3840326 to your computer and use it in GitHub Desktop.
Cheapo caching for PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Set elsewhere before including: | |
// | |
// $template = contains file to be read when fresh content is served | |
// CACHE_TTL_SECONDS = how long the cache should live, defaults to 10 mins | |
// | |
// Note: this does not necessarily save your server from receiving the GET request, | |
// you simply don't serve any content over the wire if the caching headers match, | |
// and you might save some disk I/O. | |
if (! isset($template)) { | |
header("HTTP/1.1 500 Internal Server Error", true, 500); | |
header("Content-Length: 0", true); | |
exit(); | |
} | |
if (! defined("CACHE_TTL_SECONDS")) { | |
define("CACHE_TTL_SECONDS", 600); | |
} | |
define("DATE_RFC2616", "D, d M Y H:i:s T"); | |
$lastModifiedOut = $_SERVER["REQUEST_TIME"]; | |
$etagOut = md5($_GET["ts"]); | |
$etagIn = isset($_SERVER["HTTP_IF_NONE_MATCH"]) ? trim($_SERVER["HTTP_IF_NONE_MATCH"], "\"") : ""; | |
$lastModifiedIn = isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) ? strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) : 0; | |
$cacheExpires = $_SERVER["REQUEST_TIME"] + CACHE_TTL_SECONDS; | |
// Save the intertubes if the previous request was fresh enough. | |
// Unfortunately, we can't rely on only either of If-None-Match or | |
// If-Modified-Since. Thus it'snot fully conforming to the spec. | |
// But it's pretty close and certainly better than nothing. | |
if ( | |
$etagIn === $etagOut && | |
$lastModifiedIn > $_SERVER["REQUEST_TIME"] - CACHE_TTL_SECONDS | |
) { | |
header("HTTP/1.1 304 Not Modified", true, 304); | |
header("ETag: \"" . $etagOut . "\""); | |
header("Expires: " . gmdate(DATE_RFC2616, $lastModifiedIn)); | |
header("Cache-Control: max-age=" . CACHE_TTL_SECONDS . ", must-revalidate, public"); | |
header("Content-Length: 0"); | |
exit(0); | |
} | |
// Attempt to detect the file's encoding from a sample of it's contents | |
$charset = "UTF-8"; | |
if (function_exists("mb_detect_encoding")) { | |
$sample = file_get_contents($template, false, null, 0, 200); | |
$charset = mb_detect_encoding($sample, "UTF-8,ISO-8859-1,ASCII"); | |
} | |
// Attempt to detect the file's content type | |
$ctype = "text/html"; | |
if (function_exists("finfo_open") && defined("FILEINFO_MIME_TYPE")) { | |
$fi = finfo_open(); | |
$ctype = finfo_file($fi, $template, FILEINFO_MIME_TYPE); | |
finfo_close($fi); | |
} | |
// Serve fresh HTML | |
header("HTTP/1.1 200 Found", true, 200); | |
header("Content-Type: " . $ctype . "; charset=" . $charset); | |
header("ETag: \"" . $etagOut . "\""); | |
header("Last-Modified: " . gmdate(DATE_RFC2616, $lastModifiedOut), true); | |
header("Age: 0"); | |
header("Expires: " . gmdate(DATE_RFC2616, $cacheExpires), true); | |
header("Cache-Control: max-age=" . CACHE_TTL_SECONDS . ", must-revalidate, public"); | |
readfile($template); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment