Image Caching – Specifically for Firefox

Ok so it’s Friday and it’s 2:45pm. So close to the weekend and i just spent an hour or so figuring out how to get my image caching to work on my thumbnails. Against all odds i have managed to get firefox to cache images properly – well maybe how i want it is a better term

So let me explain my thumbnail creator – Thumbercules, as i have named it (in reference to Gumbercules, a line said my Zoidberg on Futurama (Gumbercules, in reference to someone having the flexibility of Gumbi and the strength of Hercules)), dynamically created thumbnails at a certain height and width specified in the Url that i call eg http://www.domain.com/webimages/x/756/y/160/src/slideshows/images/4a288b1905e1b.jpg. It will check my thumb folder for an already created copy. If it finds one it will return the image from the folder. If not it creates the file then returns it.

What was happening with my previous caching method was that Firefox would download the image, if i pressed reload it would use the cached version it had. But if i pressed reload again it would download it again and start the process over again. It wasn’t recreating the image, only clearing the cache.

So numerous tests were performed until i was able to come up with the following:

function returnImageFile($fileName, $imageType)
{
$expires = 10800;
header("Expires: " . gmdate("D, d M Y H:i:s", strtotime( "+$expires seconds")) . " GMT");
header("Cache-Control: public, max-age=$expires, pre-check=$expires");
header("Pragma: cache", true);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
// if the browser has a cached version of this image, send 304
header("Last-Modified: " . gmdate('D, d M Y H:i:s', filemtime($fileName)).' GMT');
header("HTTP/1.1 304 Not Modified");
die;
}else if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == filemtime($fileName)))
{
// option 2, if you have a file to base your mod date off:
// send the last mod time of the file back
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fileName)).' GMT',
true, 304);
header("HTTP/1.1 304 Not Modified");
die;
}else
{
header("Last-Modified: " . gmdate('D, d M Y H:i:s', filemtime($fileName)).' GMT');
}
switch ($imageType)
{
case '1':
case 'gif':
header("Content-type: image/gif");
ob_start();
readfile($fileName);
$ImageData = ob_get_contents();
$ImageDataLength = ob_get_length();
ob_end_clean();
header("Content-Length: ".$ImageDataLength);
echo $ImageData;
break;
case '2':
case 'jpg':
case 'jpeg':
header("Content-type: image/jpeg");
ob_start();
readfile($fileName);
$ImageData = ob_get_contents();
$ImageDataLength = ob_get_length();
ob_end_clean();
header("Content-Length: ".$ImageDataLength);
echo $ImageData;
break;
case '3':
case 'png':
header("Content-type: image/png");
ob_start();
readfile($fileName);
$ImageData = ob_get_contents();
$ImageDataLength = ob_get_length();
ob_end_clean();
header("Content-Length: ".$ImageDataLength);
echo $ImageData;
break;
}
die;

This script returns the file with the size value as well as the correct headers to cache the file. If you don’t want to cache the image then you should change the approach slightly, i can’t see many times where you would require thumbnails to not be cached. But for other dynamically created images refer to my other post about creating non cached images. Firefox Caches Images when it Shouldn’t

If anyone has any points to make please do make them, i haven’t had a chance to test this well on IE or Safari. As they don’t have an easy to use plugin like firebug, which tells you when something is being returned from cache or not.

As always good luck with your programming, hopefully this saves someone some of the hassle, or at least saves someone more time then it took me to write this

You can leave a response, or trackback from your own site.

Leave a Reply