How to add a captcha to your website
Captcha is the acronym for <Completely Automated Public Turing test to tell Computers and Humans Apart>.
It is a very popular technique that tries to do exactly what it's name implies: to tell humans and computers (bots) apart. This can be useful to websites in order to distinguish form submissions made by humans (legitimate), or form submissions made by bots (usually spam).
Before we set up an example, lets see how does captcha work.
On page load, we create a session named -for example- "captcha" and as a value we give it a series of alphanumeric characters, usually from 4 to 6.
This alphanumeric series we also present as a picture in our page, asking the user to copy the identified characters into a field. The field is also submitted as part of our <form> tag.
Upon submission, the script compares the characters of that field to the already created session named "captcha".
If the content matches the session's value we continue with the form process. If not, we stop any further process and return a "wrong captcha" error.
Pretty simple, isn't it?
Now lets see an example script of the above described function:
Let's start by checking if the session exists, and if yes, create a new one. Also set the number of characters our captcha is going to have.
<?php
session_start();
if(isset($_SESSION['captcha'])){
unset($_SESSION['captcha']);
}
$num_chars=5; // number of characters for captcha image
Now, let's specify the array of the characters that will form the series. Here we have excluded the letters "l,m,n,o" and the numbers "1 and 0" in order to avoid confusion. We proceed with the construction of the characters sequence and we store that in a session.
$characters=array_merge(range(2,9),range('a','k'),range('p','z')); // creating combination of numbers & alphabets
shuffle($characters); // shuffling the characters
$captcha_text="";
for($i=0;$i<$num_chars;$i++){ // getting the required random 5 characters
$captcha_text.=$characters[rand(0,count($characters)-1)];
}
$_SESSION['captcha'] = $captcha_text; // assigning the characters to the session
Now it's time to create the image. To do that we will use a canvas as background and a set of fonts. The font that we will use for this job is "Times New Yorker". We will place the file "times_new_yorker.ttf" in a folder named "font" and will include in in our script.
header("Content-type: image/png"); // setting the image type as png
$captcha_image=imagecreatetruecolor(120,32); // create the captcha image
$captcha_background=imagecolorallocate($captcha_image,225,238,221); // setting captcha background colour
$captcha_text_colour=imagecolorallocate($captcha_image,58,94,47); // setting cpatcha text colour
imagefilledrectangle($captcha_image,0,0,120,32,$captcha_background); // creating the rectangle
$font='font/times_new_yorker.ttf'; // setting the font path
imagettftext($captcha_image,22,0,14,25,$captcha_text_colour,$font,$captcha_text); // write the text
imagepng($captcha_image); // image created here
imagedestroy($captcha_image); // image destroyed
While most of the above steps are self-explanatory, I will go through them quickly:
We create a header specifying the image type (Here it's .png), and then we create the image.
Then we set the background color and the font color, and we create the rectangle that will contain the text.
Next we specify the font folder and we write the text.
That image we export as .png, and right after we destroy it since we don't need it anymore (it already shows in our page).
Now for the full code:
<?php
session_start();
if(isset($_SESSION['captcha'])){
unset($_SESSION['captcha']);
}
$num_chars=5; // number of characters for captcha image
$characters=array_merge(range(2,9),range('a','k'),range('p','z')); // creating combination of numbers & alphabets
shuffle($characters); // shuffling the characters
$captcha_text="";
for($i=0;$i<$num_chars;$i++){ // getting the required random 5 characters
$captcha_text.=$characters[rand(0,count($characters)-1)];
}
$_SESSION['captcha'] = $captcha_text; // assigning the characters to the session
header("Content-type: image/png"); // setting the image type as png
$captcha_image=imagecreatetruecolor(120,32); // create the captcha image
$captcha_background=imagecolorallocate($captcha_image,225,238,221); // setting captcha background colour
$captcha_text_colour=imagecolorallocate($captcha_image,58,94,47); // setting cpatcha text colour
imagefilledrectangle($captcha_image,0,0,120,32,$captcha_background); // creating the rectangle
$font='font/times_new_yorker.ttf'; // setting the font path
imagettftext($captcha_image,22,0,14,25,$captcha_text_colour,$font,$captcha_text); // write the text
imagepng($captcha_image); // image created here
imagedestroy($captcha_image); // image destroyed
?>
Now save this as "captcha.img.php" and place it in a folder which must be accessible by the web server.
In the same location also place the folder that contains the .ttf (font file).
To use it, we call it as the "src" in an <img> tag. Like this:
<img src="path/to/captcha_folder/captcha.img.php" />
On every page load the previous session and image are being destroyed, and we are presented with new ones.
Although not fully "bot-proof" this script will repell the vast majority of bots that will try to submit our form.
Some bots might manage to read the characters, but we want these characters to be easily readable by people too, so we can be a little flexible here.