Using HTTP IF MODIFIED SINCE with PHP

Article Explaining how to use the HTTP IF MODIFIED SINCE with PHP, and enjoy the benefits from lower bandwidth usage.

The IF_MODIFIED_SINCE http request-header, is a header which is sent by most browsers. The header basically asks the server if the page was modified after the last visit, if that was the case, the resource is downloaded again.

If the requested resource wasn't modified since the last visit, the server returns a 304 Not Modified http Response code, and the resource is not downloaded.

There however is a difference when dealing with static pages and dynamic pages. The IF_MODIFIED_SINCE header is normally set by the server, but when you use a server-sided scripting language, like php, then you must set these on your own. This Article Explains how to do this in your PHP Scripts

Static Pages

Normally you wont have to do anything with static pages, just make sure your server support the IF_MODIFIED_SINCE header.

To check whether or not your server supports the If-Modified-Since Header, simply upload a simple HTML page to your server, request it with your browser, edit it, and request it again. If the content in your browser changed, then its safe to assume that everything is working.

A more secure way to check if its working, is to download a plugin for your browser, which shows the headers, and response codes. Firefox has a number of such useful plugins.

Dynamic Pages

This includes websites made with server-sided scripting, such as PHP, and/or programming. These pages normally don't send the correct headers, unless they are coded, or programmed to do so.

If-Modified-Since with PHP

Below is an example of how to use IF_MODIFIED_SINCE with PHP.

$fp = fopen($_SERVER["SCRIPT_FILENAME"], "r"); 
$etag = md5(serialize(fstat($fp))); 
fclose($fp); 
header('Etag: '.$etag); 
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $SelectS['LTIME'])." GMT");
header("Etag: $etag"); 

You should note that the $SelectS['LTIME'] Variable holds the timestamp from the LTIME field in your database, this is the date/time at which the requested content was last modified. The timestamp is saved in the database, using the unix format with php time(), but it may be better to use a real date format, to avoid having to deal with leap years etc.

Note. Its a good idea to have a field in your table, for both the date of postage, and the date of which the entry was last edited.

Now its just a PHP if then else, situation. I.e.

if ((@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $SelectS['LTIME']) && ( 
    trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)) { 
    header("HTTP/1.1 304 Not Modified");
    exit;
}

The Etag Header

The Etag header is usually sent to the browser by the server, and is used to check if the requested resource has changed since the last visit. The browser then sends this back to the server, contained in the HTTP_IF_NONE_MATCH request header.

Developers can use the Etag Header, to ensure that the script itself didn't change. This is usually done by generating an md5 hash from the content of the script, and sending it in the Etag header. But it could in theory contain anything the developer decide.

The Full Code Required

The full code required, excluding the database connection, and related queries. Is shown below:

$fp = fopen($_SERVER["SCRIPT_FILENAME"], "r"); 
$etag = md5(serialize(fstat($fp))); 
fclose($fp); 
header('Etag: '.$etag); 
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $SelectS['LTIME'])." GMT");
header("Etag: $etag"); 

if ((@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $SelectS['LTIME']) && ( 
    trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)) { 
    header("HTTP/1.1 304 Not Modified");
    exit;
}

You should place this somewhat in the top of your source code, either directly in the script, or as an include. And before any output is sent to the browser, including http headers.

Benefits

The main benefits are related to bandwidth usage. Sites that make use of the IF MODIFIED SINCE Header, generally save a lot of bandwidth.

Search engines

Search engines that use this header, will also benefit, in that, they won't have to waste resources crawling pages that didn't change. And thats why some of them may say to make sure that your server supports the HTTP IF MODIFIED SINCE Header.

Comment by Kostas

Posted The:20/11/2011 At: 10:20

Hi,

I am new to this so I would appreciate if you could give an example of the full code with full php syntax, cause i tried to use it as it is and it didn't work.

My site's address is www.fetchit.gr

Thanx in advance

Kostas

Author: Kostas

Comment by Roland

Posted The:18/07/2011 At: 23:12

Hi,

Could you please help me?

I make a script but IE doesn't send the header 'HTTP_IF_MODIFIED_SINCE', how can i fix?

Author: Roland

Post comment

Links that you insert are not nofollowed, but will be removed by admins if they are considered spam.

[url=Absolute URL for page]TITLE[/url]

You should insert code boxes around code examples, which will be automatically syntax highlighted.

[code1 html|css|javascript|php|sql]Your Code Here[/code1]

You may want to read our Privacy Policy before submitting your comment.