doConditionalGet() is a generic PHP function that implements HTTP’s Conditional GET mechanism.
Sending the full contents of a webpage over the Internet whenever a client requests that page is a waste of resources (CPU, memory, bandwidth, time) if the client has retrieved this page before and the content has not changed since. The inventors of HTTP came up with an idea to prevent such wastages. In a single query, the client (browser, proxy, HTTP accelerator, etc.) can say, “I have a copy of this page from a previous visit. If the page has changed since my last visit, give me a fresh copy. Otherwise, tell me that the page is unchanged and give me nothing.”
The HTTP Conditional GET mechanism also allows web servers to instruct clients to ask if the content of the requested page has changed on every visit (Cache-Control: must-revalidate), or to not ask and simply assume that the content is unchanged for a certain amount of time (Cache-Control: max-age=X).
Web servers like Apache automatically handle the Conditional GET mechanism for static objects like HTML, CSS, JavaScript, image files. This is not the case with dynamically generated content like PHP pages. Sometimes, this is a good thing because we do not want browsers or proxies to cache dynamic content that changes on every visit, or content that is sensitive or personal and should not be shared by more than one client. However, PHP-generated content is often no different from normal HTML pages that seldom change, or can be allowed to grow “stale” for a certain amount of time. Furthermore, if revalidation of a PHP page can be performed much more quickly than executing the entire page, even revalidation on every visit might make sense, improving site performance while ensuring that visitors never see stale content.
Usage
doConditionalGet() sends the “304 Not Modified” header and aborts script execution if the client has a good cached copy of the given document, otherwise it returns control to your main script to output content like normal. You must provide the function with a Last Modified date, ETag, and optionally a freshness duration for the given document. doConditionalGet() must be called before any content has been outputted. You can either call this function at the top of your script or use the ob_start() function to buffer and delay the output of your script till the end.
Usage Example
// get mtime of some file $mtime = filemtime($some_file); // set ETag to MD5 hash of filename+mtime $etag = '"'.md5($some_file.$mtime).'"'; // make cacheable by anyone, fresh for 1 minute $cache_control = 'public,max-age=60'; doConditionalGet($mtime, $etag, $cache_control);
Please see the script file for more in-depth documentation. Also see the Zenphoto plugin httpCacheControl for a “real-life” example.
Download
Changelog
November 30, 2007
- return mtime in UNIX timestamp instead of RFC1123 format for more flexibility
November 28, 2007
- rearranged logic of function to improve performance
- can now set any Cache-Control header with the third parameter
- automatically set Expires header with max-age value if available
November 27, 2007
- use GMT instead of local time
- removed ETag generation to make function more generic
- comply with the updated RFC2616 #13.3.4 when both IMS and INM headers exist (see discussion)
- code cleanup and documentation
Credit
Based on the work of
References
- RFC 2616 - Section 13
- Ned Martin’s Site Guide — Caching
- Implementing support for Conditional Get with PHP
- Cache-Friendly PHP Applications
- PHP Cache Control script
- Cache Control with PHP
If you liked this post, please subscribe to my feed. Thanks for visiting!


This is really interesting. I’ve been playing around with the POST to GET design pattern for ’saving’ state and I’ve been very interested in caching in PHP lately.