Back to home

Caching generated images with PHP

For a project we need to perform some image operations on lots of dynamically generated images and then serve these images to thousands of people. For this I had to find a way to minimize server load and traffic.  Somehow caching, which seems like a trivial task, means lots of reading because most information you'll find when googling isn't correct.  Most people mix up headers, use wrong date formats, etc..  I found one correct way to enable client-side caching using the Cache-control header. 

/*
 * Send an png file to the browser enabling client-side cache which works on:
 * Mac OSX:  Firefox 9.01,  Safari 5.1.2, Opera 11.5, Chrome 16.0.9
 * Windows: IE 9 (8,7 not tested), Chrome 16.0.9, Firefox 7.0, Firefox 9.01
 * Does not work on Windows Safari 5.01
 */
function sendFileToBrowser($imageFile) {
	header('Content-type: image/png');
	header('Content-transfer-encoding: binary');
	header('Content-length: '.filesize($imageFile));
	header('Cache-control: public, max-age=30');
	readfile($imageFile);
	exit;
}

I created this function to send png images which are generated when necessary back to the user with the correct headers. I tested if the caching worked by monitoring the HTTP response and requests to my apache server. When you test this yourself, do not use CTRL+R (Windows), CMD+R (Mac) to reload the page as this invalidates the cache. You should open a new tab/window and enter the URL there. Only Safari 5.0 on Windows seems to be having problems with this.  In short when you need to cache generated images (by i.e. PHP) you only need to send the Cache-control header.  You can set some flags in this header, like public, which means that clients/browsers must also cache the data for secure pages (https).  The must-revalidate is tricky with safari; it doesn't seem to work. Check the specs for more information about this.