Skip to content

Instantly share code, notes, and snippets.

@duzun
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duzun/9d719acea9c582eedd6f to your computer and use it in GitHub Desktop.
Save duzun/9d719acea9c582eedd6f to your computer and use it in GitHub Desktop.
Set cache control headers and manage http cache logic
/**
* Set cache control headers and manage http cache logic.
*
* @param (int|bool) $expires: true - use cache, false - no cache, int - expires timeout
* @param (time) [$modified]: Last modification time stamp
* @param (string) [$etag]: ETag content identifier
* @param (int) [$die]: 0 - no die, 1 - die on 304, -1 - no 304 headers
*
* @return (mixed) status code if cache, false if headers sent, true otherwise
*
* @author Dumitru Uzun
*/
function header_cache($expires=true, $modified=NULL, $etag=NULL, $die=true, $cc=NULL) {
if(headers_sent()) return false;
defined('DATE_HTTP') or define('DATE_HTTP', 'D, d M Y H:i:s T');
$time = time();
header("Date: ".gmdate(DATE_HTTP, $time));
// Cache-Control: no-cache,max-age=0
// Pragma: no-cache
$hcc = get_env('HTTP_CACHE_CONTROL');
$hpg = get_env('HTTP_PRAGMA');
if($hcc || $hpg) {
$t = explode(',', $hcc.','.$hpg);
$rcc = array(); // request Cache-Control
foreach($t as $v) if($v = trim($v)) {
$v = explode('=', $v, 2);
if(count($v) == 2) {
$rcc[$v[0]] = trim($v[1]);
}
else {
$v = reset($v);
$rcc[$v] = $v;
}
}
if(!empty($rcc['no-cache'])) {
$expires = false;
}
elseif($expires && @$rcc['max-age'] == '0') {
$expires = 0;
}
unset($t, $v);
}
if(is_int($expires) || $expires) {
isset($cc) or $cc = defined('CACHE_CONTROL') ? CACHE_CONTROL : 'public';
$cc and header("Pragma: $cc");
if(is_int($expires)) {
// isset($prot) or $prot = get_env('SERVER_PROTOCOL') or $prot = 'HTTP/1.0';
header('Expires: ' . gmdate(DATE_HTTP, $time+$expires)); // HTTP/1.0
$cc and $cc = ' ' . $cc . ',';
header("Cache-Control:$cc max-age=$expires"); // HTTP/1.1
}
$fresh = NULL; // NULL - undefined, true - fresh, false - old
if( $modified > 0 ) {
header('Last-Modified: '.gmdate(DATE_HTTP, $modified));
if($fresh !== false ) {
if($ms = get_env('HTTP_IF_MODIFIED_SINCE')) {
$fresh = ($modified <= strtotime($ms));
} // else - first visit or not suported
}
}
if( $etag ) {
header('ETag: '.$etag);
if($ms = get_env('HTTP_IF_NONE_MATCH') or $fresh) {
$fresh = ($ms == $etag);
} // else - first visit or not suported
}
if(isset($fresh)) {
if($fresh === true) {
$code = 304;
if($die >= 0) {
$msg = 'Not Modified';
if(strncmp(php_sapi_name(), 'cgi', 3) == 0) {
header("Status: $code $msg", true, $code);
}
else {
isset($prot) or $prot = get_env('SERVER_PROTOCOL') or $prot = 'HTTP/1.1';
header("$prot $code $msg", true, $code);
}
if($die) {
while(ob_get_level() > 0) ob_end_clean();
flush();
die();
}
}
return $code;
}
else {
return 200;
}
}
}
else {
header('Pragma: no-cache');
header('Expires: 0');
header('Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0');
}
return true;
}
// A helper function to get an environment/server variable
function get_env($var) {
if(func_num_args() > 1) {
$t = func_get_args();
return get_env($t);
}
if(is_array($var)) {
foreach($var as $v) {
$t = get_env($v);
if($t !== false) return $t;
}
}
else {
$t = getenv($var);
if($t === false && array_key_exists($var, $_SERVER)) {
$t = $_SERVER[$var];
}
}
return $t;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment