PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store
Related Articles

Anti-Spam Techniques In PHP, Part 2

Implementing A PHP CAPTCHA Solution

We will now implement the actual PHP code to do this.

The first thing that needs to be done is to install the Text_CAPTCHA class. At time of writing, this classes also depends on Text_Password and Image_Text, so if you don’t already have these they must also be installed.

In order to install these via the Linux command line, you should use commands similar to the following:

Listing 1 Commands used to install PEAR's Text_CAPTCHA (listing-1.txt)
# pear install -f Text_CAPTCHA
# pear install -f Image_Text

The captcha.php file

This is the script that generates the CAPTCHA image. This script assumes that a phrase has already been set in the session.

Additionally, you must have TrueType font present in the same directory as captcha.php. This is the font used to write the secret phrase. If you use a Windows computer, you can find a bunch of these in your C:\Windows\Fonts directory.

The captcha.php file looks like this, from start to end:

Listing 2 captcha.php
<?php
    require_once('Text/CAPTCHA.php');
 
    session_start();
    $phrase = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : 'Error';
 
    $options = array('font_size' => 24,
                     'font_file' => 'georgia.ttf');
 
    $cap = Text_CAPTCHA::factory('Image');
    $cap->init(120, 60, $phrase, $options);
 
    header('Content-type: image/png');
    echo $cap->getCAPTCHAAsPNG();
?>

Note that this doesn’t do any error checking, so you may want to improve this. Additionally, the text used if no phrase was found is “Error”, so if this is the case, then this text will appear in the image, and the user will probably never be able to complete submission of the form.

Now, here’s the PHP code for the form and form processor. Note that the whole thing has been over-simplified, and real form-processing would have much more to it than this.

Listing 3 listing-3.php
<?php
    session_start();
 
    if (isset($_POST['process'])) {
        if (!isset($_SESSION['captcha']))
            die('Form accessed incorrectly');
 
        if (isset($_POST['captcha']) && $_POST['captcha'] == $_SESSION['captcha']) {
            die('CAPTCHA text matched! Phrase was ' . $_SESSION['captcha']);
        }
        else {
            die('CAPTCHA text did not match. Phrase was ' . $_SESSION['captcha'] . ', you entered ' . $_POST['captcha']);
        }
    }
    else {
        // generate a new CAPTCHA phrase
        $_SESSION['captcha'] = substr(md5(uniqid(null)), 0, 4);
   }
?>
<html>
    <head>
        <title>CAPTCHA Demo</title>
    </head>
    <body>
        <form method="post" action="<?= $_SERVER['PHP_SELF'] ?>">
            <img src="captcha.php" /><br />
            Enter phrase: <input type="text" name="captcha" /><br />
 
            <input type="submit" name="process" value="Submit" />
        </form>
    </body>
</html>

In this code, we’re just generating a random string of text using MD5 and uniqid() for our phrase. This has a lot of scope for improvement or change, although this will do the trick.

That’s all there is to it! The images generate by Text_CAPTCHA are somewhat straightforward. There are other implementations on the Internet for creating CAPTCHA images, but essentially they all do the same thing and the algorithm I’ve provided above will work with all of them.

In This Article