Serving Images from Database with Browser Caching.
Introduction.In my news-feed web app, the page is generated by a PHP script. It can include numerous images that are drawn from a database. I had been struggling to get the browser to cache these images so the page would load quickly, to no avail. Nothing I tried seemed to have any effect. I would still see larger images appearing band by band as the images were loading thanks to my slow Internet connection.
But then I discovered Smirnoff - well, not really, but I discovered this page. It is a little terse, so I thought I would explain my resulting PHP script. Now I'm a happy man - the page loads like lightening (well by my standards), and after the first time, the images are just there.
Changes - step 1, no query string.One of the things I had tried first, and have retained, is the elimination of a query string. Originally I would give a src attribute for the images of the form britseyeview.com/feed/getimg.php?id=1234. I thought this might make some browsers reluctant to cache the image, so now the URLs are of the form britseyeview.com/feed/getimg.php/1234. The '1234' here is supplementary path information. The PHP handles this with:
The substr is there to remove the leading slash that you'll find on $_SERVER["PATH_INFO"].
Changes - step 2, timestamp your images.My images database table already had an automatically populated timestamp column, so I did not have anything to do there. If you haven't you'll have to add one and populate it with times in suitably distant past.
Changes - step 3, get your head around HTTP_IF_MODIFIED_SINCE.The thing that causes the browser to send an HTTP_IF_MODIFIED_SINCE header is, somewhat counter-intuitively, an incoming header that tells it it must revalidate the URL it is requesting. That's what I had been missing all the time ;=( There are other headers:
These get sent the first time the browser requests your images. On subsequent requests it should then send the magic header, which we can compare with the timestamp from the database (this must be in Unix Time format). Something like:
There is a little more to do to make the browser start from scratch if you modify your PHP image server script, but you'll see that in the final version:
Bingo! My page is much more nippy, and I don't eat though my paid-for bandwidth at the same rate ;=)