Controlling Browser Cache PHP

One hassle of writing dynamic Web pages is the behavior of caches. Browsers maintain their own cache, and by default they will check for a newer version of the page only once per session. Some ISPs provide their own cache as well. The intention is to avoid wasteful retransmission of pages. However, if the content on your page potentially changes with each request, it can be annoying if an old version appears. If you are developing an e-commerce site, it can be critical that each page is processed anew.

On the other hand, your page may be dynamically building a page that contains information that doesn't change very often. My experience has been that caches are smart enough to store URLs that appear to be ordinary HTML files, but not URLs that contains variables following a question mark. Your PHP may use variables in the URL, though. If the information on these pages changes infrequently, you want to let the cache know. RFC 2616 describes the HTTP 1.1 protocol, which offers several headers for controlling the cache. The headers to send to prevent a page from being cached.

The Last-Modified header reports the last time a document was changed, and setting it to the current time tells the browser this version of the page is fresh. The Expires header tells the browser when this version of the document will become stale and should be requested again. Again we use the current time, hopefully causing the browser to keep the document out the cache. Perhaps the most important header, Cache-Control tells the browser how to cache the page. In this situation, weare requesting the page not be cached. The fourth header is for the benefit of older browsers that understand only HTTP 1.0. Try reloading thescript. You should see the date update each time.

<?
header("Last-Modified: " . gmdate("D, d M Y
H:i:s") . " GMT");
header("Expires: " . gmdate("D, d M Y H:i:s") . "
GMT");
?>
<HTML>
<TITLE>Listing 18.3</TITLE>
<BODY>
The time is <? print(date("D, d M Y H:i:s")); ?><BR>
</BODY>
</HTML>

It causes a page to be cached for 24 hours. The Last- Modified, Expires and Cache-Control headers are used to control cache behavior. The last modification time is sent as the actual modification of the file. The expiration time is sent as 24 hours from now. And the cache is instructed to let the document age for 86,400 seconds, the number of seconds in a day. To prove to yourself that the file is being returned by the cache, try reloading the page quickly. The dates on the page should remain the same.

Notice that all the dates in these two examples use GMT, or Greenwich Mean Time. This is specified by the HTTP protocol. Forgetting to convert from your local time zone to GMT can be an annoying source of bugs.

<?
//report actual modification time of script
$LastModified = filemtime(__FILE__) + date("Z"); header("Last-Modified: " . gmdate("D, d M Y H:i:s",$LastModified) . " GMT");
//set expiration time 24 hours (86400 seconds) from now
$Expires = time() + 86400; header("Expires: " . gmdate("D, d M Y H:i:s",$Expires) . " GMT");
//tell cache to let page age for 24 hours (86400 seconds)
?>
<HTML>
<? print(gmdate("D, d M Y H:i:s", $LastModified)); ?> GMT<BR> It expires <? print(gmdate("D, d M Y H:i:s",$Expires)); ?> GMT<BR>