Recently on a project I was developing using the Zend Framework, I needed to validate a form using a CAPTCHA image.

CAPTCHA

For those who don’t know, CAPTCHA stands for Completely Automated Public Turing test to tell Computers and Humans Apart.

Here’s a list of what we need to do to get our instance of Zend_Captcha_Image up and running.

  1. Make sure we have GD installed.
  2. Make a new folder in our web directory with 777 permissions. This will store the generated CAPTCHA images.
  3. Write generateCaptcha() function
  4. Write validateCaptcha() function
  5. Show a quick example, bask in Zend Framework aided CAPTCHA awesomeness, and stop fearing robots until the Matrix comes true

1.) Make sure we have GD installed.

2.) Make CAPTCHA images folder

Create a folder in public/ directory to store image with write pwrmission I of course mean whatever folder your server is pointing to. This is so the captcha images can be accessible by HTTP request, for example through the folder http://www.your-site.com/public/images/captcha/

I hope you’re deep enough in the game for that to make sense. After you’ve made that folder, take note of it, for you’ll use it in step 3.

3.) Write generateCaptcha() function


  1. //generates an instance of Zend_Captcha
  2. //returns ID of captcha session
  3. function generateCaptcha() {
  4. $captcha = new Zend_Captcha_Image();
  5. $captcha->setTimeout(’300′)
  6. ->setWordLen(’6′)
  7. ->setHeight(’80′)
  8. ->setFont(‘/path/to/your/fontFile.ttf’)
  9. ->setImgDir(‘/path/to/your/image/captchaDirectory’);
  10. $captcha->generate();    //command to generate session + create image
  11. return $captcha->getId();   //returns the ID given to session & image
  12. }   //end function generateCaptcha

So, let’s go over this function. First we instantiated a new Object of class Zend_Captcha_Image. Then we used it’s functions to feed it some basic information. $captcha->setTimeout(’300′) sets the time the session will stay active, in seconds. So, upon loading the form, the user has 5 minutes to respond. ->setWordLen(’6′), pretty obviously sets how many characters are used in the CAPTCHA image. 6 is pretty decent, as shown in the example above. ->setHeight(’80′) sets the heigh of the image. The default may be good for you; I only chose it because my font file was a bit big.

->setFont(‘/path/to/your/fontFile.ttf’) points to which font you want to use for the image. I’d recommend a san serif font, as others may be too hard for humans to read. Do a quick google search for .ttf files, you should find one online without too much trouble. Contact me if you want one that I used though!

Finally, ->setImgDir(‘/path/to/your/image/captchaDirectory’) should point to the directory you created in step 2.

Let’s talk abit about what the Zend Framework is doing for us with the generate(); command. Basically, it makes a random string of numbers and lower case letters and makes an image out of this using your font and some GD trickery/artistry to make it look funny, and more importantly – (even more) non robot readable. Then, it stores all the information in a session called up by…

4.) Write validateCaptcha() function


  1. //validates captcha response
  2. function validateCaptcha($captcha) {
  3. $captchaId = $captcha[‘id’];
  4. $captchaInput = $captcha[‘input’];
  5. $captchaSession = new Zend_Session_Namespace(‘Zend_Form_Captcha_’ . $captchaId);
  6. $captchaIterator = $captchaSession->getIterator();
  7. $captchaWord = $captchaIterator[‘word’];
  8. if( $catchaWord ) {
  9. if( $captchaInput != $captchaWord ){
  10. return false;
  11. } else {
  12. return true;
  13. }
  14. } else {
  15. return false;
  16. }
  17. }

vaidateCaptcha() is pretty simple as well. First, you get data sent by the form through the function in $captcha, an array you set up in the controller later on. It contains 2 pieces of information, – the CAPTCHA session’s id, and what the user (hopefully human!) entered into the form. Using the id, it accesses the session, and gets the correct word. The word is compared to what the input entered, and the function returns appropriately.

5.) This is where you make it clap

Here’s a quick example of what the code would look like in the backend + frontend. I’ll write the code using Zend’s MVC standards if someone requests, but I think you guys can figure this out.

  1. //setup CAPTCHA
  2. $captchaId = generateCaptcha();        //generates CAPTCHA image and session, returns session’s ID
  3. if( isset($_POST[‘captcha’]) ) {       //if a post value is sent, process form
  4. $captcha = $_POST[‘captcha’];     //get array sent in $_POST form
  5. if( validateCaptcha($captcha) ) {
  6. //if a true value is sent, process form
  7. } else {
  8. //captcha invalid, text doesn’t match
  9. }
  10. }

And now the frontend.

  1. <!–?=$_SERVER[‘PHP_SELF’] ?–><form action=”<?=$_SERVER['PHP_SELF'] ?>” method=”POST”>
  2. <img src=”/your/captchaDirectory/<!–?=$captchaId ?–><?=$captchaId ?>.png” alt=”"/><br />
  3. What‘s the word above say? <input />
  4. <input value=”<!–?=$captchaId ?–><?=$captchaId ?>”/>
  5. <input value=”test me”/>

</form>