PHP Captcha

by Vincy. Last modified on July 19th, 2022.

When allowing users to enter data into our website, we need to check whether the data is entered by the human. Otherwise, people will use robots to push the bulk of unwanted data into the website.

Allowing malicious access will cause a lot of problems. For example, XSS attack or SQL injection and more.

Sometimes it will increase server load and let it down. It may annoy your regular users due to the unavailability of the website.

Captcha is one of the best remedies for this hazard. It prevents anonymous access and stops robots from sending data.

View Demo

CAPTCHA is an unpredictable random code. It is generated in run time. It can be in a variety of modes. For example,

  • Text mode
  • Audio mode
  • graphical mode and more

On submitting the user input, it validates the captcha code entered by the user. This validation will help to capture the robot not entering the captcha code.

Generate Captcha Code in Custom PHP

PHP example to generate Captcha code for a contact form

This is to know how to generate Captcha code using core PHP. I have created this example without using any third-party plugins.

It has minimal and structural code by which you can have a clear idea about how it works.

It contains a contact form to get names, email, message subject and messages from the users. I have creates a captcha and displays it in the form. The captcha is mandatory to submit the form.

Php Captcha File Structure

I used PHP built-in GD library to create captcha images. I generate a random key and supply it to the captcha image layer.

I have used the PHP session to manage the current captcha session.

Captcha element in HTML contact form

I created a contact form and render a Captcha input into it.

This code shows the HTML to display the form with the Captcha code.

The input element named captcha_code is the target to display the captcha.

I used CSS to set the captcha image as the background of this input field. I did this for the design aesthetics of embedding the captcha.

We can also show the captcha image as an individual image element in the form.

<title>Contact Form with PHP Captcha</title>
<link href="./assets/css/style.css" type="text/css" rel="stylesheet" />
	<h2>Contact Form with PHP Captcha</h2>
	<form name="frmContact" method="post" action="">
		<table border="0" cellpadding="10" cellspacing="1" width="100%"
			<tr class="tablerow">
				<td width="50%">Name<br /> <input type="text" name="userName"
					class="demo-input" required></td>
				<td width="50%">Email<br /> <input type="email" name="userEmail"
					class="demo-input" required></td>
			<tr class="tablerow">
				<td colspan="2">Subject<br /> <input type="text" name="subject"
					class="demo-input" required></td>
			<tr class="tablerow">
				<td colspan="2">Content<br /> <textarea name="content"
						class="demo-input" rows="5" required></textarea></td>
			<tr class="tablerow">
				<td>Captcha Code: <span id="error-captcha" class="demo-error"><?php if(isset($error_message)) { echo $error_message; } ?></span>
					<input name="captcha_code" type="text"
					class="demo-input captcha-input">
				<td><br /> <input type="submit" name="submit" value="Submit"
<?php if(isset($success_message)) { ?>
<div class="demo-success"><?php echo $success_message; ?></div>
<?php } ?>

PHP code to create captcha

The captchaImageSource.php file is the background source of the captcha element. This file creates a random token and embeds it on a dynamically created image source.

The below PHP code shows how it works. It requires the Captcha.php Model class. It has methods to create, manage and validate the captcha.

After creating captcha images, the renderCaptchaImage() function tiles the captcha onto the form. It sends a header for returning captcha resources to the browser.

namespace Phppot;

use Phppot\Captcha;
require_once "./Model/Captcha.php";
$captcha = new Captcha();
$captcha_code = $captcha->getCaptchaCode(6);
$captcha->putSession('captcha_code', $captcha_code);
$imageData = $captcha->createCaptchaImage($captcha_code);

In this PHP class, the getCaptchaCode() creates a 6 digit token. It is to display a random key in the captcha layer. I used PHP random_bytes(64) to get the random key.

I used a PHP session to store the captcha and validate it with the user data.

The create captcha image function generates the captcha image dynamically. With the use of the PHP GD library function, this is quite easy to generate.

It creates a JPEG resource and returns it to the contact form. The below code shows the Captcha.php class functions.

namespace Phppot;

class Captcha

    function getCaptchaCode($length)
        $random_alpha = md5(random_bytes(64));
        $captcha_code = substr($random_alpha, 0, $length);
        return $captcha_code;

    function setSession($key, $value)
        $_SESSION["$key"] = $value;

    function getSession($key)
        $value = "";
        if (! empty($key) && ! empty($_SESSION["$key"])) {
            $value = $_SESSION["$key"];
        return $value;

    function createCaptchaImage($captcha_code)
        $target_layer = imagecreatetruecolor(72, 28);
        $captcha_background = imagecolorallocate($target_layer, 204, 204, 204);
        imagefill($target_layer, 0, 0, $captcha_background);
        $captcha_text_color = imagecolorallocate($target_layer, 0, 0, 0);
        imagestring($target_layer, 5, 10, 5, $captcha_code, $captcha_text_color);
        return $target_layer;

    function renderCaptchaImage($imageData)
        header("Content-type: image/jpeg");

    function validateCaptcha($formData)
        $isValid = false;
        $capchaSessionData = $this->getSession("captcha_code");

        if ($capchaSessionData == $formData) {
            $isValid = true;
        return $isValid;

Validating Captcha code in server-side

After generating and displaying the captcha code, the next step is validation.

After the form submits, the validation takes place in the PHP end. The below code shows how it compares user data with the current captcha session.

It returns a boolean true or false based on which the process will go forward.

I used the database to store the contact data once the captcha validation returns true. This code also shows form-data sanitization with PHP filter_var() function.

use Phppot\Captcha;
use Phppot\Contact;

require_once "./Model/Captcha.php";
$captcha = new Captcha();
if (count($_POST) > 0) {
    $userCaptcha = filter_var($_POST["captcha_code"], FILTER_SANITIZE_STRING);
    $isValidCaptcha = $captcha->validateCaptcha($userCaptcha);
    if ($isValidCaptcha) {
        $userName = filter_var($_POST["userName"], FILTER_SANITIZE_STRING);
        $userEmail = filter_var($_POST["userEmail"], FILTER_SANITIZE_EMAIL);
        $subject = filter_var($_POST["subject"], FILTER_SANITIZE_STRING);
        $content = filter_var($_POST["content"], FILTER_SANITIZE_STRING);
        require_once "./Model/Contact.php";
        $contact = new Contact();
        $insertId = $contact->addToContacts($userName, $userEmail, $subject, $content);
        if (! empty($insertId)) {
            $success_message = "Your message received successfully";
    } else {
        $error_message = "Incorrect Captcha Code";


This is the output screenshot for a contact form with a custom captcha. This screen shows a text captcha code in an image format.

The green division shows acknowledgment denoting the successful submission of the form with a valid captcha.

Captcha Form Success

Once the user entered invalid captcha, the PHP captcha validation script will return false. Then, it will send the error message to update the UI as shown below.


View DemoDownload

Written by Vincy, a web developer with 15+ years of experience and a Masters degree in Computer Science. She specializes in building modern, lightweight websites using PHP, JavaScript, React, and related technologies. Phppot helps you in mastering web development through over a decade of publishing quality tutorials.

Comments to “PHP Captcha”

Leave a Reply

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

↑ Back to Top

Share this page