Create a Simple Captcha Script Using PHP


Demo Download

We all have encountered captcha validation in online web forms. Basically captcha are used to check that weather you are human or a bot. These captcha images contains some readable text with some noise, shape, distortion, lines and dots, which are readable by human and who can write it into the captcha input field to confirm that user is human, not a bot.

There are ready made third party captcha plugins available on the internet such as ReCaptcha, aim of this tutorial is to share knowledge that how captcha works and how can we create our own custom captcha.

Requirement:

Please make sure that GD(Graphics Draw) library is installed on your host. Mostly web host already have it. But if you don’t then you can install it, follow instructions or ask you web hosting company to install it.

Readers Also Read: How to Implement Custom CSRF Token in PHP

Steps to create a Captcha Using PHP

  1. Create an index.php file
  2. Create a captcha.php file

1. Create an index.php file

First of all I will create an index file, in this file I will create a html form of captcha. I will also add JavaScript that will refresh captcha without refreshing page. After captcha form submission, entered captcha code will be validated with the generated captcha code. If both are same user will see a message of success otherwise failure.

Now create index.php page and copy paste the below html captcha form in it.

HTML

<form name="form" method="post" action="">
<label><strong>Enter Captcha:</strong></label><br />
<input type="text" name="captcha" />
<p><br />
<img src="captcha.php?rand=<?php echo rand(); ?>" id='captcha_image'>
</p>
<p>Can't read the image?
<a href='javascript: refreshCaptcha();'>click here</a>
to refresh</p>
<input type="submit" name="submit" value="Submit">
</form>

JavaScript

<script>
//Refresh Captcha
function refreshCaptcha(){
    var img = document.images['captcha_image'];
    img.src = img.src.substring(
		0,img.src.lastIndexOf("?")
		)+"?rand="+Math.random()*1000;
}
</script>

Add the above JavaScript in the footer of index.php. This script will refresh the captcha if it is very difficult to read, so that user can insert new captcha code.

PHP Script

Enter the below php validation script in the header of index.php file, before starting the <html> tag.

<?php
session_start();
$status = '';
if ( isset($_POST['captcha']) && ($_POST['captcha']!="") ){
// Validation: Checking entered captcha code with the generated captcha code
if(strcasecmp($_SESSION['captcha'], $_POST['captcha']) != 0){
// Note: the captcha code is compared case insensitively.
// if you want case sensitive match, check above with strcmp()
$status = "<p style='color:#FFFFFF; font-size:20px'>
<span style='background-color:#FF0000;'>Entered captcha code does not match! 
Kindly try again.</span></p>";
}else{
$status = "<p style='color:#FFFFFF; font-size:20px'>
<span style='background-color:#46ab4a;'>Your captcha code is match.</span>
</p>";	
	}
}
echo $status;
?>

The above script is matching the captcha code with the users input and showing message of success or failure.

2. Create a captcha.php file

Now most important step, create a captcha.php file and copy paste the below script in it.

PHP Script

<?php
session_start();
//You can customize your captcha settings here

$captcha_code = '';
$captcha_image_height = 50;
$captcha_image_width = 130;
$total_characters_on_image = 6;

//The characters that can be used in the CAPTCHA code.
//avoid all confusing characters and numbers (For example: l, 1 and i)
$possible_captcha_letters = 'bcdfghjkmnpqrstvwxyz23456789';
$captcha_font = './monofont.ttf';

$random_captcha_dots = 50;
$random_captcha_lines = 25;
$captcha_text_color = "0x142864";
$captcha_noise_color = "0x142864";


$count = 0;
while ($count < $total_characters_on_image) { 
$captcha_code .= substr(
	$possible_captcha_letters,
	mt_rand(0, strlen($possible_captcha_letters)-1),
	1);
$count++;
}

$captcha_font_size = $captcha_image_height * 0.65;
$captcha_image = @imagecreate(
	$captcha_image_width,
	$captcha_image_height
	);

/* setting the background, text and noise colours here */
$background_color = imagecolorallocate(
	$captcha_image,
	255,
	255,
	255
	);

$array_text_color = hextorgb($captcha_text_color);
$captcha_text_color = imagecolorallocate(
	$captcha_image,
	$array_text_color['red'],
	$array_text_color['green'],
	$array_text_color['blue']
	);

$array_noise_color = hextorgb($captcha_noise_color);
$image_noise_color = imagecolorallocate(
	$captcha_image,
	$array_noise_color['red'],
	$array_noise_color['green'],
	$array_noise_color['blue']
	);

/* Generate random dots in background of the captcha image */
for( $count=0; $count<$random_captcha_dots; $count++ ) {
imagefilledellipse(
	$captcha_image,
	mt_rand(0,$captcha_image_width),
	mt_rand(0,$captcha_image_height),
	2,
	3,
	$image_noise_color
	);
}

/* Generate random lines in background of the captcha image */
for( $count=0; $count<$random_captcha_lines; $count++ ) {
imageline(
	$captcha_image,
	mt_rand(0,$captcha_image_width),
	mt_rand(0,$captcha_image_height),
	mt_rand(0,$captcha_image_width),
	mt_rand(0,$captcha_image_height),
	$image_noise_color
	);
}

/* Create a text box and add 6 captcha letters code in it */
$text_box = imagettfbbox(
	$captcha_font_size,
	0,
	$captcha_font,
	$captcha_code
	); 
$x = ($captcha_image_width - $text_box[4])/2;
$y = ($captcha_image_height - $text_box[5])/2;
imagettftext(
	$captcha_image,
	$captcha_font_size,
	0,
	$x,
	$y,
	$captcha_text_color,
	$captcha_font,
	$captcha_code
	);

/* Show captcha image in the html page */
// defining the image type to be shown in browser widow
header('Content-Type: image/jpeg'); 
imagejpeg($captcha_image); //showing the image
imagedestroy($captcha_image); //destroying the image instance
$_SESSION['captcha'] = $captcha_code;

function hextorgb ($hexstring){
  $integar = hexdec($hexstring);
  return array("red" => 0xFF & ($integar >> 0x10),
               "green" => 0xFF & ($integar >> 0x8),
               "blue" => 0xFF & $integar);
			   }
?>

In the above code, I include a font name monofont $captcha_font = ‘./monofont.ttf’; you can use any font that you want otherwise you can download this font from here.

Make sure that you keep this font in the same folder where you are keeping index.php and captcha.php files.

Now you can browse index.php file on your local host or online web host if you have. Our captcha form is now ready to use.

Explanation:

I have used comments to explain each step in the above code. However, I will also explain their working separately. captcha.php file is performing the following actions to create a captcha:

  • Creating a blank image with white background
  • Creating random dots
  • Creating random lines
  • Creating random 6 letters on image

Creating a blank image with white background

Following script is generating a blank image with height 50px and width 130px.

$captcha_image_height = 50;
$captcha_image_width = 130;
$captcha_image = @imagecreate(
	$captcha_image_width,
	$captcha_image_height
	);
$background_color = imagecolorallocate(
	$captcha_image,
	255,
	255,
	255
	);
header('Content-Type: image/jpeg'); 
imagejpeg($captcha_image);

Creating random dots

Following script is generating random dots in the image background.

$random_captcha_dots = 50;
$captcha_noise_color = "0x142864";
$array_noise_color = hextorgb($captcha_noise_color);

$image_noise_color = imagecolorallocate(
	$captcha_image,
	$array_noise_color['red'],
	$array_noise_color['green'],
	$array_noise_color['blue']
	);

for( $count=0; $count<$random_captcha_dots; $count++ ) {
imagefilledellipse(
	$captcha_image,
	mt_rand(0,$captcha_image_width),
	mt_rand(0,$captcha_image_height),
	2,
	3,
	$image_noise_color
	);
}

function hextorgb ($hexstring){
  $integar = hexdec($hexstring);
  return array("red" => 0xFF & ($integar >> 0x10),
               "green" => 0xFF & ($integar >> 0x8),
               "blue" => 0xFF & $integar);
			   }

Creating random lines

Following script is generating random lines in the image background.

$random_captcha_lines = 25;

for( $count=0; $count<$random_captcha_lines; $count++ ) {
imageline(
	$captcha_image,
	mt_rand(0,$captcha_image_width),
	mt_rand(0,$captcha_image_height),
	mt_rand(0,$captcha_image_width),
	mt_rand(0,$captcha_image_height),
	$image_noise_color
	);
}

Creating random 6 letters on image

Following script is generating random 6 letters and putting them on the captcha image.

$captcha_code = '';
$total_characters_on_image = 6;
$possible_captcha_letters = 'bcdfghjkmnpqrstvwxyz23456789';
$captcha_font = './monofont.ttf';
$captcha_text_color = "0x142864";

$count = 0;
while ($count < $total_characters_on_image) { 
$captcha_code .= substr(
	$possible_captcha_letters,
	mt_rand(0, strlen($possible_captcha_letters)-1),
	1);
$count++;
}

$captcha_font_size = $captcha_image_height * 0.65;

$array_text_color = hextorgb($captcha_text_color);
$captcha_text_color = imagecolorallocate(
	$captcha_image,
	$array_text_color['red'],
	$array_text_color['green'],
	$array_text_color['blue']
	);

$text_box = imagettfbbox(
	$captcha_font_size,
	0,
	$captcha_font,
	$captcha_code
	); 
$x = ($captcha_image_width - $text_box[4])/2;
$y = ($captcha_image_height - $text_box[5])/2;
imagettftext(
	$captcha_image,
	$captcha_font_size,
	0,
	$x,
	$y,
	$captcha_text_color,
	$captcha_font,
	$captcha_code
	);

Always destroy the image instance after creating captcha image, using imagedestroy($captcha_image);

You may also noticed that I started session_start();  in the beginning of the page because I need to store a random generated captcha value in session variable $_SESSION[‘captcha’] = $captcha_code; to compare with the user input value for validation purpose.

Demo Download

If you found this tutorial helpful, kindly share it with your friends and developer groups.

Facebook Official Page: All PHP Tricks

Twitter Official Page: All PHP Tricks

Article By
Javed Ur Rehman is a passionate blogger and web developer, he loves to share web development tutorials and blogging tips. He usually writes about HTML, CSS, JavaScript, Jquery, Ajax, PHP and MySQL.
  1. Hi, I had problems with
    $x = ($captcha_image_width – $text_box[4])/2;
    $y = ($captcha_image_height – $text_box[5])/2;
    I had to transform them to int:
    $x = intval(($captcha_image_width – $text_box[4])/2);
    $y = intval(($captcha_image_height – $text_box[5])/2);
    otherwise imagettftext() did not work

  2. Sir how if I want to implement to my login form?
    Can u guide me sir?
    I want user can’t login if type wrong captcha
    many thanks sir

    1. Dear Billy, yes you can implement this captcha code to any form including login form. You just need to create logic in your login form and implement this tutorial captcha script to make it working. Although, I try to help as much as possible to the readers of my tutorials. However, If you need urgent help, you can always hire me for freelance service.

      1. Thankyou so much sir your code help me a lot
        finally I just used callback method to my login form to enable button when finish the captcha.

  3. (you can disregard my last comment… I had the php code above the tag but below the html declaration

    Once I moved it, it worked perfectly!

    Thank you!

    1. Dear Joe, first try to run my code on localhost XAMPP, if it is working on local environment then you can check your phpinfo on localhost and ask your hosing to do the same which is missing there.

  4. Thank you Mr Javed Ur Rehman — this s truely a simple Catcha for login and comment captcha (I add “required” element) then it work perfect.
    I’m looking for this tip a long time, and now this is my solution into comment form.. with DEMO file, everything become too simple. thank you !

  5. Can you please help in telling where I’m lacking as I followed the right steps but digits are not showing

    1. First try to generate random numbers and digits, follow this step: Creating random 6 letters on image, in here first try to print them on webpage instead of image, if they are printing then print them on image.

      1. I entered wrong captcha still its accepting .
        and now I am entering right captcha then its displaying msg like wrong match

  6. Hello

    I able to see the captcha box on website form but numbers are not displaying , only lines and dots are showing

  7. Sir How To enables ,
    throw error..
    Fatal error: Uncaught Error: Call to undefined function imagecreate() in C:\xampp\htdocs\Omesh\sws2\captcha.php:31 Stack trace: #0 {main} thrown in C:\xampp\htdocs\Omesh\sws2\captcha.php on line 31

  8. Hi Javed. My previous comment didn’t show the complete information. I implmented the Captcha on my site and it works perfect; great work! I really appreciated; however, it does not work if I set ” Header set Content-Security-Policy “script-src ‘self’ ” on my .htaccess file; it does not refresh. Do you now how could I solve this conflict? Thanks in advance.

  9. Hi Javed. I implmented the Captcha on my site and it works perfect; great work! I really appreciated; however, it does not work if I set <> on my .htaccess file; it does not refresh. Do you now how could I solve this conflict?

    Thanks in advance.

  10. I wasted so much time trying to figure out why my implementation accepted the form if they didn’t enter anything, only to now realize that your entire script does not work because it totally just accepts a blank entry and that is true even on your demo. What a huge waste of time.

    1. Well you can make the field required using html attribute or JavaScript. I was supposed to explain the captcha here therefore I didn’t explain the field required attribute here. Simply add required=’required’ in the captcha input field. Hope this help you out.

    2. You mean to tell me, that you couldn’t write in to the form process the proper code to stop the form from being submitted if the the captcha field was not filled in and did not equal the $_SESSION[‘captcha’]

      You need to go to school beother

  11. Good day, Thanks for the Captcha Tutorial and source code and can easily to understand, and I can use on my website, but one problem is the Font Directory, need to use ($captcha_font = dirname(__FILE__) . “./monofont.ttf”;) from ($captcha_font = ‘monofont.ttf’;) to correct the file path of font(font-family to use), I found this error when I remove the header and search for an alternative way for Font Dir path. thanks

  12. First let me say thank you for your time. I appreciate you sharing this knowledge.

    I first tested the captcha just as you described with a BLANK actin URL for the web form and it works just as you would expect. However, once I deployed it within a real web form using my URL for the action contact form, even setting the input captcha text filed as required, the form is sent successfully while completely ignoring IF the captcha is accurate or not.

    I don’t understand HOW to include this in a REAL web form where the captcha is not ignored and your code actually monitors if a human is processing the web form.

    I appreciate your help!

    1. Hi Jon, Captcha compares the code with the session value. Kindly make sure that session is enabled on your host. Sometimes sessions are not able to pass from one page to another, in this case contact your hosting provider.
      If session is not the issue, then you will need to debug the code.
      Simply print/echo the captcha value after form submission and also print the session value that is stored in session for captcha text validation.

  13. Hi,
    I am using you module in magento for custom form. Its working fine when I was using it on Apache server. But when I changed my server to ukfast.co.uk nginx server it show me error Error filtering template: Notice: Undefined index: captcha for session variables. Please help me.

    1. Right click on the image and open in new tab to make sure if image is creating correctly or not. Also make sure that image library is enabled on localhost to generate image.

  14. Works fine in localhost but not in live site.
    Captcha image is not displaying just a thumb is there. Any idea?

    1. Follow the tutorial step by step and see the result, at first you must see the blank image, check the image URL in code inspector and copy paste the image URL in new tab of browser to check

  15. Hi
    Thanks for your post , this is exactly what i needed.
    How does the javascript get the new captcha without sending a new
    request?
    thanks in advanced

  16. Hi Javed,

    I have used your captcha module in different places and working well.

    Recently I deployed the same module on the newly configured Ubuntu 16.04 server which has PHP 5.6.40 installed.

    I copied your complete demo but it is also not displaying the numbers. Do not show any error message too.
    All works fine, but only TEXT not displaying. I checked the font file and everything as it is in your demo.

    I checked for php-gd library for 5.6 and installed it correctly. You can view the configuration from here:

    Could you please assist me? I searched a lot, but failed. What are dependencies that should be installed to run this function? I think some modules have missed.

    I look forward to hearing from you soon.
    Bye

    1. I think that there is something font related issue, you may try with another font file. Or you enter random number by yourself, comment mt_rand() function and hard code any number for testing purpose.

  17. Hey, Numbers doesn’t show and I got this error:
    [01-Feb-2019 13:14:09 UTC] PHP Warning: imagettfbbox(): Could not find/open font in C:\inetpub\wwwroot\assets\captcha.php on line 89
    [01-Feb-2019 13:14:09 UTC] PHP Warning: imagettftext(): Could not find/open font in C:\inetpub\wwwroot\assets\captcha.php on line 101

  18. Hello sir, I tried to run your captcha using xampp latest version but the image cannot be display.

    I wonder if I should try to run it with older version of xampp or should I run with another application.

    Your help is much appreciate.

    1. HI Ran, i don’t think that this is xampp issue, may be you should try to create image using PHP, check are you able to create image in PHP?
      If you are not able to create image using php, better to look into this first. @imagecreate() i am using this function for this purpose. I have mentioned all steps to create image. Before captcha you should know how to create image using php.

  19. I love the awesome post! I read your posts often and I shared this post on my Facebook and my followers loved it.
    Keep up the awesome work.

  20. Hi sir I need your help badly
    I want this captcha on my website i need only captcha like this, please help me how can I add only captcha there? I am trying more than 4 months but no results I only learnt to make this type of captcha from you but when I tried to add this my site It shows nothing only missing image please help me to make a script for my site thank you you are only my last hope please help me asap please

    1. Dear Sumit, this is the error of image source, so you are providing incorrect source url, if image is not available on the provided source URL then you will get the same error, i will also suggest you to first implement my script on your machine and then implement it. Also try to keep Captcha script on same website, because you are using different website for captcha code, i never have experience of creating captcha on another website.

      1. Could you please help me to add captcha on this page, please?

        could you provide me with a good captcha validation code, please?

        site is here

        I need CAPTCHA for this site Please help

Leave a Reply

Your email address will not be published. Required fields are marked *