3 Steps Simple Captcha With PHP – Free Script Download

Welcome to a tutorial on how to create a simple PHP captcha. Have a website that is constantly being spammed by angry troll keyboard warriors? Time to put in some security and prevention measures.

The general steps to building a simple captcha in PHP are:

  1. When the user accesses the page to be secured, start the session and generate a random captcha string.
  2. Create the captcha image using the GD extension.
  3. Embed the captcha image into the HTML form, challenge the user to enter the captcha string.
  4. Upon submission, countercheck the user’s entered captcha against the session – Proceed only if they match.

Let us walk through an actual example in this guide, without the use of any 3rd party frameworks – Read on!

ⓘ I have included a zip file with all the source code at the end of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes PHP Captcha Useful Bits
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

  • Please enable the GD extension extension=gd (gd2 prior to PHP8) in php.ini.
  • Edit 1-captcha.php, function draw() – Choose a font $font from your system and make sure that the path is correct.
  • Launch 2-form.php in your browser, that’s all.
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

PHP CAPTCHA

All right, let us now get into the details of creating a simple PHP captcha.

 

STEP 1) PHP CAPTCHA CLASS

captcha.php
<?php
class Captcha {
  // (A) PRIME THE CAPTCHA - GENERATE RANDOM STRING IN SESSION
  function prime ($length=8) {
    $char = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $max = strlen($char) - 1;
    $random = "";
    for ($i=0; $i<=$length; $i++) {
      $random .= substr($char, rand(0, $max), 1);
    }
    $_SESSION["captcha"] = $random;
  }

  // (B) DRAW THE CAPTCHA IMAGE
  function draw ($output=1, $width=300, $height=100, $fontsize=24, $font="C:\Windows\Fonts\arial.ttf") {
    // (B1) OOPS.
    if (!isset($_SESSION["captcha"])) { throw new Exception("CAPTCHA NOT PRIMED"); }

    // (B2) CREATE BLANK IMAGE
    $captcha = imagecreatetruecolor($width, $height);

    // (B3) FUNKY BACKGROUND IMAGE
    $background = "captcha-back.jpg";
    list($bx, $by) = getimagesize($background);
    if ($bx-$width<0) { $bx = 0; }
    else { $bx = rand(0, $bx-$width); }
    if ($by-$height<0) { $by = 0; }
    else { $by = rand(0, $by-$height); }
    $background = imagecreatefromjpeg($background);
    imagecopy($captcha, $background, 0, 0, $bx, $by, $width, $height);

    // (B4) THE TEXT SIZE
    $text_size = imagettfbbox($fontsize, 0, $font, $_SESSION["captcha"]);
    $text_width = max([$text_size[2], $text_size[4]]) - min([$text_size[0], $text_size[6]]);
    $text_height = max([$text_size[5], $text_size[7]]) - min([$text_size[1], $text_size[3]]);

    // (B5) CENTERING THE TEXT BLOCK
    $centerX = CEIL(($width - $text_width) / 2);
    $centerX = $centerX<0 ? 0 : $centerX;
    $centerX = CEIL(($height - $text_height) / 2);
    $centerY = $centerX<0 ? 0 : $centerX;

    // (B6) RANDOM OFFSET POSITION OF THE TEXT + COLOR
    if (rand(0,1)) { $centerX -= rand(0,55); }
    else { $centerX += rand(0,55); }
    $colornow = imagecolorallocate($captcha, rand(120,255), rand(120,255), rand(120,255)); // Random bright color
    imagettftext($captcha, $fontsize, rand(-10,10), $centerX, $centerY, $colornow, $font, $_SESSION["captcha"]);

    // (B7) OUTPUT AS JPEG IMAGE
    if ($output==0) {
      header("Content-type: image/png");
      imagejpeg($captcha);
      imagedestroy($captcha);
    }

    // (B8) OUTPUT AS BASE 64 ENCODED HTML IMG TAG
    else {
      ob_start();
      imagejpeg($captcha);
      $ob = base64_encode(ob_get_clean());
      echo "<img src='data:image/jpeg;base64,$ob'/>";
    }
  }

  // (C) VERIFY CAPTCHA
  function verify ($check) {
    // (C1) CAPTCHA NOT SET!
    if (!isset($_SESSION["captcha"])) { throw new Exception("CAPTCHA NOT PRIMED"); }

    // (C2) CHECK
    if ($check == $_SESSION["captcha"]) {
      unset($_SESSION["captcha"]);
      return true;
    } else { return false; }
  }
} 

// (D) CREATE CAPTCHA OBJECT
session_start(); // Remove if session already started
$PHPCAP = new Captcha();

First, we start with the “core engine”, the Captcha library. Yes, this looks complicated at first, but keep calm and explore it slowly. Not going to explain line-by-line, but this library essentially only has 3 functions!

Function Description
prime() Part 1 of the process, which will create a random alphanumeric captcha string and put it into $_SESSION["captcha"]. The default is 8 characters, and if you want a longer and harder captcha challenge, simply specify a longer $length when calling this function.
draw() Part 2, which generates the captcha image. A reminder to change the font path here again or GD will not be able to render properly.
verify() The last part which verifies a given captcha string – Simply match it against $_SESSION["captcha"] and returns a true/false.

 

 

STEP 2) GENERATE CAPTCHA IN HTML FORM

2-form.php
<form id="demo" method="post" action="3-submit.php">
  <!-- (A) FORM FIELDS -->
  <label for="name">Name:</label>
  <input name="name" type="text" required/>
  <label for="email">Email:</label>
  <input name="email" type="email" required/>
 
  <!-- (B) CAPTCHA HERE -->
  <label for="captcha">Are you human?</label>
  <?php
  require "1-captcha.php";
  $PHPCAP->prime();
  $PHPCAP->draw();
  ?>
  <input name="captcha" type="text" required/>
 
  <!-- (C) GO! -->
  <input type="submit" value="Go!"/>
</form>

This should not be too difficult.

  • Section A is the “usual form fields”.
  • The important part here is section B, generating the captcha.
    • Captain Obvious, require "1-captcha.php" to include the library.
    • Call the $PHPCAP->prime() function to generate a random captcha string into the session.
    • Call the $PHPCAP->draw() function to generate the captcha image.

That’s all.

 

 

STEP 3) CAPTCHA VERIFICATION UPON SUBMISSION

3-submit.php
<?php
// (A) CAPTCHA CHECK
$result = "";
require "1-captcha.php";
if (!$PHPCAP->verify($_POST["captcha"])) {
  $result = "CAPTCHA does not match!";
}
 
// (B) PROCEED IF CAPTCHA CHECK OK
if ($result == "") {
  // DO SOMETHING
  $result = "Congrats, CAPTCHA is correct.";
}
 
// (C) THE END
print_r($_POST);
echo $result;

On submitting the form, we only need to use $PHPCAP->verify($_POST['captcha']) to check if the user has entered the correct captcha – Proceed if the challenge passed, or show an error message if it failed.

 

 

USEFUL BITS & LINKS

That’s all for the code, and here are a few small extras that may be useful to you.

 

CAPTCHA CODE IS NOT SHOWING!

Check that PHP has read permission to your specified font file. If you don’t want to mess with the “system fonts”, search and download any “free for use” web fonts – Google Fonts is your best bet.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to better fight spam in your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

3 thoughts on “3 Steps Simple Captcha With PHP – Free Script Download”

  1. Excellent code !!!…….
    Followed your quick tips and executed successfully without any errors …
    Keep uploading cool programs …..

  2. Hi,
    excellent code.
    But I have a problem. The downloaded sources placed on my localhost (PHP 7.1.8) returns no captcha code (only the background is visible).
    What’s wrong?

    1. If it is only generating the image:

      1) The captcha code is probably not primed into the session, I.E. $_SESSION[‘captcha’] is missing. Make sure that the session is started.
      2) Alternatively, the font may not be set properly; GD cannot access the font file, cannot generate the image captcha properly.

      Good luck!

Leave a Comment

Your email address will not be published.