homepage Welcome to WebmasterWorld Guest from
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

Caching PHP GD Dynamic Images
Best approach to cache images on the fly?

 11:39 pm on Oct 14, 2005 (gmt 0)

I have a PHP script that takes a handful of parameters and outputs a graphic based on those parameters. The file name is a direct representation of the input parameters. For example (widgetized):

image.php?a=red&b=big&c=png outputs the file red.big.png to the web accessible directory /output/

I've actually already picked a way of caching the output of this script but would like to discuss possible alternatives and get a feel for "best practices" in this area. Here are the two general methods of caching I had originally considered:

Method A) The PHP script is called through an <img /> tag and first uses the file_exists() function to see if the image has already been made. If it does exist, the PHP script uses the header() function and the readfile() function to output that existing image. Or if it does not exist, it generates the image, writes it to the static position then uses header() and readfile() to output the image.

Method B) The images are called using the static path in an <img /> tag. The directory /output/ uses a custom 404 error page (image.php) which parses out the $_SERVER['REQUEST_URI'] with the explode() function to populate the input parameters and generate the image. It puts the image in the static folder, then uses header() and readfile() to output the image to the server.

1. What are the pro's and cons to these two different methods of caching the images?
2. Is there any reason why either method *can't* be used?
3. What other methods are there? Or, how would you improve on these methods?

I'd appreciate your input on this subject, or if you can recommend other Apache directives/PHP functions that would be useful in this scenario.



 10:14 pm on Oct 15, 2005 (gmt 0)

I would not want to send 404s for every image not yet created, which you can't really control because you don't arrive at your php script until after the request has failed and you've been sent on the 404 page.

The other method has a tiny bit more overhead, of course, but only a tiny bit, and it should allow you to send the proper status code.


 10:44 pm on Oct 15, 2005 (gmt 0)

So the readfile() function is essentially equivalent in overhead to apache serving that same file?


 12:39 am on Oct 16, 2005 (gmt 0)

Of course the simple request to Apache for a file is going to be the fastest possible interaction with the least overhead. So I wouldn't say it's equivalent because with readfile you're running things through the PHP parser, but this should be a very small amount of overhead if you benchmark with Apache Bench.

BTW, I've done similar simply by sending the right headers and using include() for the image file. In my case it wasn't that the image file might or might not be found, but someone wanted a specific item in the DB updated whenever specific images were called. So I just did the DB updates based on the request, then sent the headers and included the image file and it worked fine.... I think. I should dig that up and make sure ;-)


 1:17 am on Oct 16, 2005 (gmt 0)

I would do something like this:

$image = 'images/blue.png';
<img src="<?php echo ( file_exists( $image ) ? $image : "image.php?a=red&b=big&c=png"; ?>" />

This should save you from any overhead that readfile might add.


 10:23 am on Oct 16, 2005 (gmt 0)

Surely there's a solution that uses mod_rewrite and the -f flag to check whether the image exists, and otherwise call your PHP script, creating and saving the image so it exists the next time it's requested...


 3:24 pm on Oct 16, 2005 (gmt 0)

I was wondering about mod_rewrite...

Perhaps something like

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} ^.*\.(gif¦jpg¦jpeg¦png)$
RewriteRule ^.*/image_dir/(.*)\.(gif¦jpg¦jpeg¦png)$ php_image_generator?params=$1


 8:40 pm on Oct 17, 2005 (gmt 0)

Thank you lobo235 for a simple to implement method of eliminating readfile entirely. :)

Seems that keeping all the caching/serving logic in the PHP scripts adds to portability and ease of updating. Does anyone feel as though there is any significant difference between using the file_exists PHP function or mod_rewrite's -f flag? I'd use mod_rewrite if it was noticeably better -- but it seems that readfile is a low overhead function and I imagine that file_exists is too.


 10:16 am on Oct 18, 2005 (gmt 0)

I haven't tested this but I'd expect that using mod_rewrite in httpd.conf would be the fastest followed by mod_rewrite in .htaccess with PHP file_exists being the slowest. But we're talking about fractions of seconds in any reasonable scenario so it's much of a muchness.



 7:48 pm on Oct 18, 2005 (gmt 0)

Realistically, whenever I benchmark things like this, you have to get up to 1000 or even 10000 iterations to get noticeable differences in execution time. Creating an image needlessly or a bunch of needless DB queries starts to really hurt, but realistically, stuff like this only hurts with huge traffic of when repeated many many times in a big script.

That said, I think if you do benchmark, drcrombie's last post is almost certain to be right.

I'm not actually sure that having it in .htaccess or httpd.conf would make that much difference *if* you're already allowing .htaccess with Allow Override. I *think* that the main drag on the server from .htaccess is enabling it at all so that the server is forced to recurse up through the directory hierarchy and check every directory for any parent .htaccess that is in force. Once you've set it to Allow Override, is httpd.conf significantly faster?

Anyway, like he said, not much of a muchness (whatever that means!).


 10:09 pm on Oct 18, 2005 (gmt 0)

Excellent info everyone. Thank you all for chiming in!

I think the one overriding theme of this thread is that time is better spent optimizing other, more processor intensive portions of dynamic image scripts. :)


 11:14 pm on Oct 24, 2005 (gmt 0)

U could use a 404 script to build the image, cahce it and output it (changing the headers back to a 200). This way there would be ZERO overhead if the image alread exists, and very little if it doesn't. It's also ellegant and simple.

Global Options:
 top home search open messages active posts  

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved