Last active
December 16, 2015 13:48
-
-
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
This file contains hidden or 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 | |
//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