Integrate Captcha Functionality with PHP Custom Library

A CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a type of challenge-response program that helps to determine whether the user is human. The CAPTCHA in the web application is used to protect the web form from bots and spam submissions. Nowadays, CAPTCHA is also used in web pages to validate user access and prevent bots from accessing the website. Mostly, you need to add CAPTCHA for protecting contact forms, comment forms, and other web forms from spam in the web application.

There are various third-party solutions are available to integrate CAPTCHA functionality into the website. One of the popular third-party CAPTCHA solutions is Google reCAPTCHA and we published the Google reCAPTCHA Integration with PHP tutorial earlier. But, if you want to create a custom PHP library for Captcha verification, this step-by-step guide helps you a lot.

You can build custom CAPTCHA library to generate Captcha image and verify Captcha code using PHP. In this tutorial, we will show you how to create CAPTCHA image and integrate Captcha verification functionality with PHP custom library.

Before getting started take a look at the file structure of the Simple PHP Captcha script.

php_captcha/
├── index.php
├── get_captcha.php
├── Captcha.class.php
├── fonts/
|   └── monofont.ttf
├── css/
    └── style.css

PHP Captcha Library (Captcha.class.php)

This Captcha class is a custom library that is used to generate images with CAPTCHA code using PHP.

  • The createCaptcha() function generates a random alphanumeric code and creates an image using the PHP GD library.
  • The Captcha code is stored in $_SESSION for further verification.
  • Various configuration options are defined to customize the Captcha image with PHP.
<?php 

class Captcha
{
    
// Configuration Options
    
var $word '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var 
$length 5;
    var 
$img_width 160;
    var 
$img_height 50;
    var 
$font_path '';
    var 
$font_size 25;
    var 
$expiration 7200;
    var 
$bg_color '#ffffff';
    var 
$border_color '#996666';
    var 
$text_color '#cc9999';
    var 
$grid_color '#ffb6b6';
    var 
$shadow_color '#fff0f0';
    
    public function 
__construct($config = array()){
        
ob_start();
        
session_start();
        if (
count($config) > 0){
            foreach (
$config as $key => $val){
                if (isset(
$this->$key)){
                    
$method 'set_'.$key;
                    if (
method_exists($this$method)){
                        
$this->$method($val);
                    }else{
                        
$this->$key $val;
                    }
                }
            }
        }
        if ( ! 
extension_loaded('gd')){
            return 
FALSE;
        }
    }
    
    public function 
createCaptcha(){
        
$str '';
        for (
$i 0$i $this->length$i++){
            
$str .= substr($this->wordmt_rand(0strlen($this->word) -1), 1);
        }
        
$word $str;

        
/* Determine angle and position */
        
$length    strlen($word);
        
$angle    = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
        
$x_axis    rand(6, (360/$length)-16);
        
$y_axis = ($angle >= ) ? rand($this->img_height$this->img_width) : rand(6$this->img_height);

        
/* Create image */
        
if (function_exists('imagecreatetruecolor')){
            
$im imagecreatetruecolor($this->img_width$this->img_height);
        }else{
            
$im imagecreate($this->img_width$this->img_height);
        }

        
/* Assign colors */
        
$bgColorRgb $this->hexToRgb($this->bg_color);
        
$borderColorRgb $this->hexToRgb($this->border_color);
        
$textColorRgb $this->hexToRgb($this->text_color);
        
$gridColorRgb $this->hexToRgb($this->grid_color);
        
$shadowColorRgb $this->hexToRgb($this->shadow_color);
        
$bg_color        imagecolorallocate ($im$bgColorRgb[0], $bgColorRgb[1], $bgColorRgb[2]);
        
$border_color    imagecolorallocate ($im$borderColorRgb[0], $borderColorRgb[1], $borderColorRgb[2]);
        
$text_color        imagecolorallocate ($im$textColorRgb[0], $textColorRgb[1], $textColorRgb[2]);
        
$grid_color        imagecolorallocate($im$gridColorRgb[0], $gridColorRgb[1], $gridColorRgb[2]);
        
$shadow_color    imagecolorallocate($im$shadowColorRgb[0], $shadowColorRgb[1], $shadowColorRgb[2]);

        
/* Create the rectangle */
        
ImageFilledRectangle($im00$this->img_width$this->img_height$bg_color);

        
/* Create the spiral pattern */
        
$theta        1;
        
$thetac        7;
        
$radius        16;
        
$circles    20;
        
$points        32;

        for (
$i 0$i < ($circles $points) - 1$i++){
            
$theta $theta $thetac;
            
$rad $radius * ($i $points );
            
$x = ($rad cos($theta)) + $x_axis;
            
$y = ($rad sin($theta)) + $y_axis;
            
$theta $theta $thetac;
            
$rad1 $radius * (($i 1) / $points);
            
$x1 = ($rad1 cos($theta)) + $x_axis;
            
$y1 = ($rad1 sin($theta )) + $y_axis;
            
imageline($im$x$y$x1$y1$grid_color);
            
$theta $theta $thetac;
        }
        
        
/* Write the text in image */
        
$use_font = ($this->font_path != '' && file_exists($this->font_path) && function_exists('imagettftext')) ? TRUE FALSE;

        
$x rand(0$this->img_width/($length/1.5));
        
$y $this->font_size+2;
        
        for (
$i 0$i strlen($word); $i++)
        {
            if (
$use_font == FALSE){
                
$y rand($this->img_height/2);
                
imagestring($im$this->font_size$x$ysubstr($word$i1), $text_color);
                
$x += ($this->font_size);
            }else{
                
$y rand($this->img_height/2$this->img_height-3);
                
imagettftext($im$this->font_size$angle$x$y$text_colordirname(__FILE__).'/'.$this->font_pathsubstr($word$i1));
                
$x += $this->font_size;
            }
        }
        
/* Create the image border */
        
imagerectangle($im00$this->img_width-1$this->img_height-1$border_color);
        
        
/* Showing the image */
        
imagejpeg($im,NULL,90);
        
header('Content-Type: image/jpeg');//image type header
        
imagedestroy($im);//destroying image
        
        /* Store captcha code into session */
        
unset($_SESSION['captchaCode']);
        
$_SESSION['captchaCode'] = $word;
    }
    
    public function 
hexToRgb($hex){
        
$hex str_replace("#"""$hex);
        if(
strlen($hex) == 3) {
           
$r hexdec(substr($hex,0,1).substr($hex,0,1));
           
$g hexdec(substr($hex,1,1).substr($hex,1,1));
           
$b hexdec(substr($hex,2,1).substr($hex,2,1));
        } else {
           
$r hexdec(substr($hex,0,2));
           
$g hexdec(substr($hex,2,2));
           
$b hexdec(substr($hex,4,2));
        }
        
$rgb = array($r$g$b);
        return 
$rgb;
    }
}

?>

Generate Captcha Image (get_captcha.php)

Initialize the Captcha class and specify the configuration options.

  • Use the createCaptcha() method of Captcha class to load the CAPTCHA image.
<?php 

// Include Captcha library
require_once 'Captcha.class.php';

// Initialize Captcha class with configuration options
$configOptions = array(
    
'img_width' => '200',
    
'img_height' => '50',
    
'font_size' => '30',
    
'font_path' => 'fonts/monofont.ttf',
);
$captcha = new Captcha($configOptions);

// Load captcha image
$captcha->createCaptcha();

?>

Display Captcha in HTML Form (index.php)

Initially, the CAPTCHA image is displayed on the webpage with a refresh link and input field.

  • Load get_captcha.php URL with HTML <img> Tag to display Captcha image.
  • Reload the get_captcha.php URL in <img> src to refresh the Captcha image using JavaScript.
  • Define the HTML input element to enter the Captcha code for verification.
<!-- Status message -->
<?php if(!empty($statusMsg)){ ?>
    <div class="alert alert-<?php echo $status?>"><?php echo $statusMsg?></div>
<?php ?>

<!-- Captcha image -->
<img src="get_captcha.php" id="capImage"/>

<!-- Reload Captch image -->
<p>Can't read the image? click here to  <a href="javascript:void(0);" onclick="javascript:document.getElementById('capImage').src='get_captcha.php';">refresh</a>.</p>

<!-- Captcha code input form -->
<form method="post">
    <div class="input-group">
        <span class="input-group-text">Enter Captcha Code:</span>
        <input type="text" name="captcha_code" class="form-control">
    </div>
    <input type="submit" name="submit" class="btn btn-primary" value="SUBMIT">
</form>

Verify Captcha Code using PHP

At the time of Captcha image generation, the code is stored in SESSION by the PHP CAPTCHA library.

  • Get the Captcha code from SESSION using PHP $_SESSION.
  • Compare user input with SESSION Captcha code.
<?php 
// Start session
if(!session_id()){
    
session_start();
}

// If the form is submitted
$status 'danger';
if(isset(
$_POST['submit'])){
    
// Check whether the captcha code input is empty
    
if(!empty($_POST['captcha_code'])){
        
// Retrieve captcha code from session
        
$captchaCode $_SESSION['captchaCode'];
        
        
// Get captcha code from user input
        
$user_captcha_code $_POST['captcha_code'];
        
        
// Verify the captcha code
        
if($user_captcha_code === $captchaCode){
            
$status 'success';
            
$statusMsg 'Captcha code verified successfully!';
        }else{
            
$statusMsg 'Captcha code not matched, please try again.';
        }
    }else{
        
$statusMsg 'Please enter the captcha code.';
    }
}
?>

Note: You can place this code at the top of the index.php file to verify the CAPTCHA code on form submission.

Conclusion

We created a custom library to integrate CAPTCHA functionality in PHP. This PHP Captcha library provides highly configurable options to customize the Captcha image and add it to the web form. You can use this script to verify user responses by Captcha challenge in HTML form using PHP.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

Leave a reply

keyboard_double_arrow_up