Web Hosting Talk







View Full Version : PHP: Image verification


mylinear
04-04-2006, 04:33 AM
I've been trying out some image verification code. The below is a simple test script to test out the functionality.

Here is what happens.
1. When first run, a new image is created and displayed on the browser.
2. When the refresh button is pressed, a new image is created and the new image is displayed on the browser.
3. When the Submit button is pressed, the script is re-called and re-run and a new image is created. This can be verified by directly viewing the test.png file. However, the new image is not displayed on the browser. The old image is still shown.

My questions are:
1. Why is it that a refresh will display the new image while the Submit does not, even though both re-run the script?
2. Is this a browser caching issue?
3. If it is a caching issue, what should be done to get the desired results?


<?php
// Create image
$random = rand(1000, 9999);
$image = imagecreate(60, 40);
$background = imagecolorallocate($image, 0, 0, 0);
$text = imagecolorallocate($image, 255, 255, 255);
imagestring($image, 5, 10, 10, $random, $text);
imagepng($image, "test.png");
imagedestroy($image);
?>
<html>
<head>
<title>Test</title>
</head>
<body>
<?php
print date("r");
print "<br />";
?>
<img src="test.png" />
<form name="Test" action="test.php" method="POST">
<input type="submit" name="Submit" value="Submit" />
</form>
</body>
</html>

zoid
04-04-2006, 07:02 AM
1. Why is it that a refresh will display the new image while the Submit does not, even though both re-run the script?
2. Is this a browser caching issue?
Most probably.

3. If it is a caching issue, what should be done to get the desired results?
You could set the appropriate HTML headers to tell the browser not to cache it (and its content) or generate the image on-the-fly in a second script (instead of outputting it to a file and then referencing this) and setting there appropriate HTTP caching headers. Something like this
<img src="image_generator.php" />

error404
04-04-2006, 08:18 AM
You really shouldn't be saving the image to a file anyway. There is some delay between when a browser requests the original script and when it will request the image. Under load a system doing that would have major issues (users would see the wrong images). What you probably should do is, when the image is created, store the text used (in the session or something). When your image generation code is called, use whatever is stored in the session variable. Then in your main code you can set the text value when you want a new CAPTCHA, or you can leave it what it was (and regenerate the same image as before), like when you submit.

mylinear
04-04-2006, 08:46 AM
You could set the appropriate HTML headers to tell the browser not to cache it


I will look into this. Interestingly, when I tried my test code as is in Firefox, it worked the way I expected it to. I was using IE earlier to test.


<img src="image_generator.php" />


Thank you for the pointer.

mylinear
04-04-2006, 08:51 AM
You really shouldn't be saving the image to a file anyway. There is some delay between when a browser requests the original script and when it will request the image. Under load a system doing that would have major issues (users would see


Yes, I realised that. That would have been my follow-up question once I got this working. How to prevent the generated image being overwritten by another user. You have answered that question for me in advance.

Thanks for your help.

sasha
04-04-2006, 09:08 AM
Images with the same name will not refresh in IE by default. You can use meta tags and headers to prevent caching of entire page or you could simply add random string to your file name `img src="img.php?r=12312312` which will force any browser to reload it every time.

zoid
04-04-2006, 09:15 AM
Although it is a browser issue, it is not a particular browser's issue, its due to caching. The best solution would be probably the mentioned image outputting script - also for the reasons noted by error404.

mylinear
04-04-2006, 11:02 AM
If anyone is interested, the following seems to work. This is based on help from zoid and error404. I think you probably need the headers to prevent caching, but I have not tried that yet.

test.php:

<html>
<head>
<title>Test</title>
</head>
<body>
<?php
print date("r");
print "<br />";
?>
<img src="test2.php" />
<form name="Test" action="test.php" method="POST">
<input type="submit" name="Submit" value="Submit" />
</form>
</body>
</html>


test2.php:

<?php
// Create image
$random = rand(1000, 9999);
$image = imagecreate(60, 40);
$background = imagecolorallocate($image, 0, 0, 0);
$text = imagecolorallocate($image, 255, 255, 255);
imagestring($image, 5, 10, 10, $random, $text);
imagepng($image);
imagedestroy($image);
?>