Home
PHP
Tech Tube
MySQL
Linux
CSS&HTML
JavaScript

PHP captcha class

This class will allow you to generate custom captcha images fast and easy. Keep in mind that if you use AJAX to submit your forms you need to generate a new captcha image after each submit. Here's a wide list of font files Font Squirrel This is a simple usage example but you may also find multiple options to customize your captcha image. Enjoy the example: Display the image in captcha_img.php
require 'samis_captcha.php';
$font = '/var/www/test.local/captcha/sewer.ttf';
$samis_captcha = new samis_captcha();
$samis_captcha->display_captcha($font);
Display and process the user (or bot) input:
require 'samis_captcha.php';
if(isset($_POST['captcha'])) {
    $samis_captcha = new samis_captcha();
    $result = $samis_captcha->check_code($_POST['captcha']);
    var_dump($result);
}
Note that the URL to the captcha image is always unique. That helps to avoid browser cache.
<form action="" method="post">
<input type="text" name="captcha" />
<img src="captcha_img.php?t=<?php echo time();?>">
<input type="submit" value="check" />
</form>
And the class itself:
<?php

/**
* This class generates captcha image using the defailt for PHP GD library.
* It also helps to check the result of the user input.
* @package Sami's captcha class
* @version $Id: samis_captcha.php v.1.0 2017-03-31 19:34:00 $
* @author Samuil Banti
* @copyright (C) 2017 - Samuil Banti
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
class samis_captcha {

    // The protected variables desciption is available in the constuctor documentation.
    protected $font 		= false; 
    protected $width 		= 200;
    protected $height 		= 50;
    protected $min_length 	= 4;
    protected $max_length 	= 6;
    protected $case_sensitive 	= false;
    protected $noice 		= false;
    protected $chars 		= array('a','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','x','y','z','2','3','4','5','6','7','8','9');
    
    /**
    * Display the captcha image.
    * NOTE: If you use AJAX to submit your form make sure that you generate a new image in the frontend.
    * @param string $font - The path to the font file that contains the symbols to be used in the captcha string. NOTE: the format of the file should be TTF.
    * @param int $width - The width of the captcha image.
    * @param int $height - The height of the captcha image.
    * @param int $min_length - The minimal length of the captcha string.
    * @param int $max_length - The maximal length of the captcha string.
    * @param array $chars - The set of chars that will be included. By default the ambiguous chars (l,o,0,1,i) are excluded.
    * @param bool $noice - If there should be an image noice. NOTE: the chars should be available in the font file.
    */
    public function display_captcha($font, $width = 200, $height = 50, $min_length = 4, $max_length = 6, $noice = false, $chars = false) {
	if(!file_exists($font)) {
	    $this->error_handler('The file "'.$font.'" does not exist or has restrictive permitions!');
	}
    
	$this->font 		= $font;
	$this->width 		= (int)$width ? $width : $this->width;
	$this->height 		= (int)$height ? $height : $this->height;
	$this->min_length 	= (int)$min_length ? $min_length : $this->min_length;
	$this->max_length 	= (int)$max_length ? $max_length : $this->max_length;
	$this->noice 		= $noice;
	$this->chars 		= ($chars && is_array($chars)) ? $chars :$this->chars;
    
        $im = $this->get_captcha_im();
        header('Content-Type: image/png');
        imagepng($im);
        imagedestroy($im);
    }
    
    /**
    * Check if the captcha code is valid. 
    * @param string $code - The input of the user or the bot.
    * @param bool $case_sensitive - If the check should be case sensitive.
    * @return bool - True if the code matches the caprcha value in the session. 
    */
    public function check_code($code, $case_sensitive = false) {
        if(!$this->is_session_started()) {
            session_start();
        }
        if(isset($_SESSION['samis_captcha'])) {
	    $samis_captcha = $_SESSION['samis_captcha'];
	    unset($_SESSION['samis_captcha']);
	    if(!$case_sensitive) {
		$code = strtolower($code);
		$samis_captcha = strtolower($samis_captcha);
	    }
	    if($code == $samis_captcha) {
		return true;
	    }
	}
        return false;
    }
    
    /**
    * Helps to debug and gives the ability to set custom error handling if you need it.
    * @param string $error_msg - The description of the error.
    */
    protected function error_handler($error_msg)
    {
	exit($error_msg);
    }
    
    /**
    * Check if the session is started.
    */
    protected function is_session_started()
    {
        if ( php_sapi_name() !== 'cli' ) {
            if ( version_compare(phpversion(), '5.4.0', '>=') ) {
                return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
            } else {
                return session_id() === '' ? FALSE : TRUE;
            }
        }
        return FALSE;
    }
    
    /**
    * Generates the captcha image.
    */
    protected function get_captcha_im() {
        if(!$this->is_session_started()) {
            session_start();
        }
        $string = $this->get_random_string();
        $_SESSION['samis_captcha'] = implode('', $string);

        $im = imagecreatetruecolor($this->width, $this->height);
        $white = imagecolorallocate($im, 255, 255, 255);
        imagefilledrectangle($im, 0, 0, $this->width, $this->height, $white);

        $rand_size1 = $this->height / 2;
        $rand_size2 = $rand_size1 + 5;
        $indent = rand($rand_size1, $rand_size2);
        foreach($string as $char) {
            $size = rand($rand_size1, $rand_size2);
            $top = $size + rand(5,10);
            $color = imagecolorallocate($im, rand(0,200), rand(0,200), rand(0,200));
            $angle = rand(0,1) ? rand(0, 25) : rand(340, 360);
            
            if($this->noice) {
                for($i=0;$i<$this->width;++$i) {
                    imagesetpixel($im, rand(0,$this->width), rand(0,$this->height), $color);
                }
            }
            imagettftext($im, $size, $angle, $indent, $top, $color, $this->font, $char);

            $indent += rand($rand_size1, $rand_size2);
        }
        return $im;
    }

    /**
    * Get a random string.
    */
    protected function get_random_string() {
        $string = array();
        $length = rand($this->min_length, $this->max_length);
        for($i=$length; $i>0; --$i) {
            $char = $this->chars[array_rand($this->chars)];
            $char = rand(0,1) ? strtoupper($char) : $char;
            $string[] = $char;
        }
        return $string;
    }
    
}

?>
Download...