A CAPTCHA image (Completely Automated Public Turing Test to Tell Computers and Humans Apart) is a novel solution to prevent spam. You will find these being used in almost all user registration pages. The most commonly used Captchas are images that look like :
The logic is quite simple.. Present a randomly generated image to the user and request that it be typed back. After the form is submitted, a check is made whether the text entered by the user matches the actual content of the graphic. If they do match, it is a human!
The rendered graphic should have sufficient noise (lines, dots, curved fonts etc) so that simple OCRs (Optical Character Readers) do not bypass it.
The Zend Framework provides a class named Zend_Captcha_Image that does all the heavy lifting required for captcha implementation. A complete working php file that demonstrates the salient points is listed below (the example has deliberately been kept simple by avoiding MVC/Zend_Form components):
//do this loop if form has been submitted!
//captcha invalid.. redisplay..
//generate a new image on every loop..note that the location of this statement is important..
//if placed before the if isset command, the captcha check will never result in true!
//display the form..
<form action=”<?php echo $_SERVER[‘PHP_SELF’]?>” method=”post”>
<p>What does the word below say?</p>
<img src=”captcha/<?php echo $captchaId?>.png” alt=”captcha”>
<input type=”text” name=”captcha[input]” />
<input type=”hidden” value=”<?php echo $captchaId?>” name=”captcha[id]” />
<input type=”submit” value=”Test me” />
Yeah.. it really is that simple!
The first two lines include the required Zend library files for use.
The next couple of lines instantiate the Zend_Captcha_Image object. Note that only the setFont() call is required.. All others are optional.
setWordLen : Number of characters in the rendered Captcha
setHeight: The height of the graphic
setFont: The font used to render the Captcha (Click here to download and use the Arial true type font)
setImgDir: The image directory where Zend will create the image files (.png). The webserver should have write permissions to this folder
setDotNoiseLevel: The noise generated by random dots in the Captcha
setLineNoiseLevel: The noise generated by random lines in the Captcha
Feel free to play around with these parameters to see the effect they have on the generated captcha image.
The next few lines of code (executed on form submit) does the check using the inbuilt method isValid() on the Captcha object. This function expects as parameter, an array containing
1. The input typed in by the user – captcha[‘input’]
2. The md5 hash of the generated captcha text that is conveniently returned by the generate() call and passed back as a hidden form variable – captcha[‘id’]
accomplishes quite a lot – It is responsible for the following:
1. Generating the captcha image and storing it in the specified image directory. PHP internally uses the gd graphics library to render the image.
2. Storing the “real value” corresponding to the image in a session variable
3. Returning an MD5 hash of the value that is generated. This hash value is used to name both the generated image file and the session variable (and that is why it needs to be passed into the isValid() method so the correct session variable can be queried)
The captcha image is created and stored in the folder specified by the setImgDir() function. The name follows the convention <md5>.png.. So, displaying the captcha to the user is simply a matter of displaying the generated image using an <img src> tag!
Zend_Captcha_Image class automatically deletes old/expired png files from the image directory (for those who don’t take my word for it, check the function _gc() routine in Zend/Captcha/Image.php.. This function is called after the generate() method – A randomization technique is employed to insure that the system does not spend too much time doing cleanup)