Skip to content

Instantly share code, notes, and snippets.

@nyamsprod
Last active December 16, 2015 13:48
Show Gist options
  • Save nyamsprod/5443903 to your computer and use it in GitHub Desktop.
Save nyamsprod/5443903 to your computer and use it in GitHub Desktop.
How to implement Browser cache using last-modified, expires and if-modified-since headers in PHP
<?php
//Datetime and related Date time function will be base on UTC Timezone
date_default_timezone_set('UTC');
$path = '/path/to/rss/feed.xml';
$max_age = '12 HOURS'; //cache time in HOURS
//1 - File Status
$file = new SplFileObject($path);
$create_file = true;
if (false !== $file->getRealPath() && file_exists($file->getRealPath())) {
$last_modified = new DateTime('@'.$file->getMtime());
if ($last_modified > new DateTime('-'.$max_age)) {
$create_file = false;
}
}
//How you save AND/OR update your resource is up to you script logic
//I use saveFeedToFile by passing the $file SplFileInfo object by reference
//the function return true if the file is correctly saved/updated
if ($create_file && saveFeedToFile($file)) {
$last_modified = new DateTime('@'.$file->getMtime()); //we create/update the $last_modified variable
}
//2 - Browser Response
if (! $file->isReadable()) {
header('HTTP/1.1 403 Forbidden');
die;
}
// Browser Cache using Expires and Last-Modified header
$expires = clone $last_modified;
$expires->modify('+'.$max_age);
header('Last-Modified: '.$last_modified->format(DATE_RFC1123));
header('Expires: '.$expires->format(DATE_RFC1123));
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
// we are using strstr because sometimes a ";" appears
// in the header and we are only interested in the Date part
// we add a semicolon in case no ";" is present otherwise strstr would return false
$last_modified <= new DateTime(strstr($_SERVER['HTTP_IF_MODIFIED_SINCE'].';', ';', true))
) {
header('HTTP/1.1 304 Not Modified');
die;
}
// We send and tell the browser to cache the ressource
header('Content-Length: '.$file->getSize());
header('Content-Type: text/xml; charset="utf-8"');
$file->rewind();
$file->fpassthru();
die;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment