This is part 1 of our PHP Captcha tutorial. It will show you how to write your very own PHP script that will generate a random captcha image. Click below to download the source code.
Spam is a serious problem on the web in the current day. Spambots can destroy entire websites through MySQL injection, cross-site scripting, posting malicious links, etc. This tutorial will teach you how to make your very own captcha system in PHP to prevent bots from spamming your site. See an example below (Refresh to generate a new captcha image).
The first thing to know is that this tutorial makes use of the GD library. Your PHP setup must have GD Support enabled to generate a captcha image. If you’re not sure whether your compilation has this feature, create a script with the following code and access it. You’ll then need to find the gd section of the configuration and see if it is enabled.
<?php phpinfo(); ?>
The basic structure of this captcha system follows.
- One PHP file is used to create the captcha image by generating a random string and placing it into an image.
- Another file contains a form which calls the first PHP file to display the captcha image.
- Using session variables you can determine whether or not the user entered the text displayed on the captcha image.
We’ll start off with our image generation script. It needs to generate a random string of a specified length, display it on an image, and store the correct answer in a session variable. Create a file named captcha.php and enter the following code into it.
<?php
session_start();
$captchaLength = 8;
$md5 = md5( microtime( ) * mktime( ) );
$key = substr( $md5, 0, $captchaLength );
$_SESSION['captcha'] = md5( $key );
$captchaImage = imagecreate( 120, 40 );
$backgroundColor = imagecolorallocate( $captchaImage, 188, 188, 188 );
$textColor = imagecolorallocate( $captchaImage, 0, 0, 0 );
$lineColor = imagecolorallocate( $captchaImage, 208, 102, 86 );
for( $i = 0; $i < 3; $i++ ) {
$lineStart = mt_rand( 0, 100 );
$lineEnd = mt_rand( 0, 100 );
imageline( $captchaImage, $lineStart, 0, $lineEnd, 40, $lineColor );
$lineStart = mt_rand( 0, 40 );
$lineEnd = mt_rand( 0, 40 );
imageline( $captchaImage, 0, $lineStart, 120, $lineEnd, $lineColor );
}
imagestring( $captchaImage, 5, 5, 10, $key, $textColor );
header( 'Content-type: image/png' );
imagepng( $captchaImage );
?>To best understand how the code above is able to generate a captcha image, we’ll break it down piece by piece.
<?php session_start();</pre> $captchaLength = 8;
The first step of this script is to start our php code with the opening <?php. The following line, session_start();, starts a PHP session. Sessions are used to store variables on your web server so they can be transferred between every page that a user visits. Sessions should only be used for temporary storage as they are destroyed after the user leaves your website. In this case, we are using session variables to store the answer to the captcha. The third line determines the length of our captcha code. If you’d like a longer or shorter string, you may change this variable.
$md5 = md5( microtime( ) * mktime( ) ); $key = substr( $md5, 0, $captchaLength ); $_SESSION['captcha'] = md5( $key );
Our next section of code generates a random string to be used in the captcha and stores it in a session variable. The first line is used to generate a random string. The two functions microtime and mktime return the current time on your server. Since time is always moving forward, this can ensure that you’ll get a random result when you multiply them. We then use the md5 function on this number in order to generate a unique hash that will be used for our captcha.
The next step is to trim this string down. an MD5 hash is always 32 characters long, so we must reduce it to our captcha length, 8 in this case. To do this we can use the substr function. Finally, we store the md5 hash of our captcha in a session variable to save for later.
$captchaImage = imagecreate( 120, 40 ); $backgroundColor = imagecolorallocate( $captchaImage, 188, 188, 188 ); $textColor = imagecolorallocate( $captchaImage, 0, 0, 0 ); $lineColor = imagecolorallocate( $captchaImage, 208, 102, 86 );
Now that we have our captcha string ready, we can start putting together the image. We’ll be using the GD library to generate our image in this example. The first step is to create our image. In this case, we’ll be using the function imagecreate(). We must pass two parameters, the width and height. Our captcha will be 120×40 pixels. Next we can generate some colors to use in the image using the function imagecolorallocate. First we generate the background color, a light gray in this case. The 3 numbers passed into the function are the RGB values of the color we are creating. For the text, we pass in three zeros to make a black color, and for the lines we are creating a red-orange color.
for( $i = 0; $i < 3; $i++ ) {
$lineStart = mt_rand( 0, 120 );
$lineEnd = mt_rand( 0, 120 );
imageline( $captchaImage, $lineStart, 0, $lineEnd, 40, $lineColor );
$lineStart = mt_rand( 0, 40 );
$lineEnd = mt_rand( 0, 40 );
imageline( $captchaImage, 0, $lineStart, 120, $lineEnd, $lineColor );
}This loop is probably the most complicated section of our script. It is used to generate a bunch of random lines in the background to confuse any bots that may try to solve our captcha. Currently it will generate 3 lines going across and 3 lines going up and down on our image. This can be changed in the loop declaration by editing the $i < 3.
Each time the loop is run a couple things happen. First, 2 random numbers are generated using the mt_rand function. They will determine the start and end points of the line. After the start and end points are determined, the imageline() function is used to draw lines. First we must pass it our image as a paramater, then the start coordinates (x = $lineStart and y = 0). Then the end coordinates (x = $lineEnd and y = 40) are passed in, followed by our line color. This code block is then repeated to generate more lines going in the other direction.
imagestring( $captchaImage, 5, 5, 10, $key, $textColor ); <pre>header( 'Content-type: image/png' ); imagepng( $captchaImage ); ?>
The last section of our script places the captcha text and outputs the image. First the imagestring() function is used to place the captcha string we generated earlier. Next, we must tell the server that this file should be interpreted as an image instead of a PHP script. We can do this with the header function. In this case, we are sending the user’s browser a header that states that this page holds a png image. Finally, we can output the image using the imagepng() function. If you’d like, it’s also not a bad idea to add a line below this with the following code.
imagedestroy( $captchaImage );
This line will destroy our image variable to free up memory on the server. Make sure it is added before the closing PHP tag.
Access your script now and you’ll see your very own captcha image. Refresh and it will be randomized each time.
In the next PHP Captcha tutorial we’ll create a form that will make use of our captcha script to prevent spambots from making submissions.
