Adding Captcha to Database using Codeigniter

Introduction

This tutorial will show you how to generate captcha image using Codeigniter Captcha Helper and store captcha characters into database. We have seen how to generate and use captcha in CodeIgniter earlier.

The CAPTCHA Helper file contains functions that assist in creating CAPTCHA images.

  • The captcha function requires the GD image library.
  • Only the img_path and img_url are required.
  • If a word is not supplied, the function will generate a random ASCII string. You might put together your own word library that you can draw randomly from.
  • If you do not specify a path to a TRUE TYPE font, the native ugly GD font will be used.
  • The “captcha” directory must be writable
  • The expiration (in seconds) signifies how long an image will remain in the captcha folder before it will be deleted. The default is two hours.
  • word_length defaults to 8, pool defaults to ‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’
  • font_size defaults to 16, the native GD font has a size limit. Specify a “true type” font for bigger sizes.
  • The img_id will be set as the “id” of the captcha image.
  • If any of the colors values is missing, it will be replaced by the default.

Related Posts:

Prerequisites

Apache HTTP Server 2.4, PHP 7.4.3, CodeIgniter 3.1.11

Create Project Directory

It’s assumed that you have setup Apache 2.4, PHP 7.4.3 and Codeigniter 3.1.11 in Windows system.

Now we will create a project root directory called codeIgniter-captcha-database under the Apache server’s htdocs folder.

Now move all the directories and files from CodeIgniter 3.1.11 framework into codeIgniter-captcha-datatabase directory.

We may not mention the project root directory in subsequent sections and we will assume that we are talking with respect to the project root directory.

Autoload Configuration

We need some configurations, such as, auto-loading for helpers to avoid loading every time we need to use.

Modify application/config/autoload.php file for auto-loading libraries and helper functions.

This one time auto-loading gives flexibility to uniformly use the helpers and libraries anywhere throughout the application without loading repeatedly.

$autoload['libraries'] = array('database', 'session');
$autoload['helper'] = array('html', 'url', 'file', 'form');

Session Configuration

By default session is saved into file system. Therefore we need to configure the path where session will be saved on disk. We will configure here temp system’s directory.

We are also setting encryption key for session data.

I have also put captcha configurations.

$config['encryption_key'] = '2d8+e6]K0?ocWp7&`K)>6Ky"|.x|%nuwafC~S/+6_mZI9/17y=sKKG.;Tt}k';
...
$config['sess_save_path'] = sys_get_temp_dir();
...
$config['captcha_form'] = TRUE;
$config['captcha_path'] = 'captcha/';
//$config['captcha_fonts_path'] = 'captcha/fonts/1.ttf';
$config['captcha_width'] = 200;
$config['captcha_height'] = 50;
$config['captcha_font_size'] = 14;
$config['captcha_expire'] = 180;
$config['captcha_grid'] = FALSE;
$config['captcha_case_sensitive'] = TRUE;

Database Configuration

Now modify application/config/database.php file to add database config:

...
'hostname' => 'localhost',
'username' => 'root',
'password' => 'root',
'database' => 'roytuts',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8mb4',
'dbcollat' => 'utf8mb4_unicode_ci',
...

Database Table

As we are going to save captcha information into database table so we will create a table captcha under roytuts database in MySQL server.

CREATE TABLE captcha (
	captcha_id bigint unsigned NOT NULL auto_increment,
	captcha_time int unsigned NOT NULL,
	ip_address varchar(45) NOT NULL,
	word varchar(20) NOT NULL,
	PRIMARY KEY `captcha_id` (`captcha_id`),
	KEY `word` (`word`)
);

View File

Create a view file captcha.php under application/views which will be used as a registration form with captcha:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?><!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Codeigniter Captcha Example</title>
        <style type="text/css">

            ::selection { background-color: #E13300; color: white; }
            ::-moz-selection { background-color: #E13300; color: white; }

            body {
                background-color: #fff;
                margin: 40px;
                font: 13px/20px normal Helvetica, Arial, sans-serif;
                color: #4F5155;
            }            

            #body {
                margin: 0 15px 0 15px;
            }

            #container {
                margin: 10px;
                border: 1px solid #D0D0D0;
                box-shadow: 0 0 8px #D0D0D0;
            }

            .error {
                color: #E13300;
            }

            .success {
                color: darkgreen;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <h1>CodeIgniter Captcha Example</h1>

            <div id="body">                
                <?php
                if (isset($success) && strlen($success)) {
                    echo '<div class="success">';
                    echo '<p>' . $success . '</p>';
                    echo '</div>';
                }
                if (validation_errors()) {
                    echo validation_errors('<div class="error">', '</div>');
                }
                ?>
                <?php
                $attributes = array('name' => 'captcha_form', 'id' => 'captcha_form');
                echo form_open($this->uri->uri_string(), $attributes);
                ?>
                <p>Email Address : <input name="email" id="email" type="text" /></p>
                <p>Password : <input name="pwd" id="pwd" type="password" /></p>
                <p>Confirm Password : <input name="cnf_pwd" id="cnf_pwd" type="password" /></p>
                <?php
                if ($captcha_form) {
                    ?>
                    <p>Captcha : <input name="not_robot" id="not_robot" type="text" /></p>
                    <p><?php echo $captcha_html; ?></p>
                    <?php
                }
                ?>
                <p><input name="register" value="Register" type="submit" /></p>
                <?php
                echo form_close();
                ?>
            </div>

        </div>
    </body>
</html>

Controller Class

Create a Controller class file captcha_form.php under application/controllers for handling client’s request and response:

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Description of Captcha
 *
 * @author https://roytuts.com
 */
class Captcha_Form extends CI_Controller {

    function __construct() {
        parent::__construct();
		$this->load->model('captcha_model', 'cm');
        $this->load->library('form_validation');
    }

    function index() {
        $captcha_form = $this->config->item('captcha_form');
        $data['captcha_form'] = $captcha_form;
        if ($captcha_form) {
            $data['captcha_html'] = $this->create_captcha();
        }
        if ($this->input->post('register')) {
            $this->form_validation->set_rules('pwd', 'Password', 'required');
            $this->form_validation->set_rules('cnf_pwd', 'Password Confirmation', 'required|matches[pwd]');
            $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
            if ($captcha_form) {
                $this->form_validation->set_rules('not_robot', 'Captcha', 'required|callback__check_captcha');
            }
            if ($this->form_validation->run()) {
                $data['captcha_html'] = $this->create_captcha();
                $data['success'] = 'You have successfully registered';
            }
        }
        $this->load->view('captcha', $data);
    }
	
	function create_captcha() {
		$this->load->helper('captcha');
        
		$cap_config = array(
            'img_path' => './' . $this->config->item('captcha_path'),
            'img_url' => base_url() . $this->config->item('captcha_path'),
            'font_path' => './' . $this->config->item('captcha_fonts_path'),
            'font_size' => $this->config->item('captcha_font_size'),
            'img_width' => $this->config->item('captcha_width'),
            'img_height' => $this->config->item('captcha_height'),
            'show_grid' => $this->config->item('captcha_grid'),
            'ip_address' => $this->input->ip_address(),
            // White background and border, black text and red grid
            'colors' => array(
                'background' => array(255, 255, 255),
                'border' => array(255, 255, 255),
                'text' => array(0, 0, 0),
                'grid' => array(255, 40, 40)
            )
        );
        
		$cap = create_captcha($cap_config);
		
		return $this->cm->_create_captcha($cap);
	}

    function _check_captcha($code) {
        if ($this->cm->check_captcha($code) == 0) {
            $this->form_validation->set_message('_check_captcha', 'Captcha is incorrect');
            return FALSE;
        }
        return TRUE;
    }

}

Model Class

To perform database activities we are going to create model class.

<?php

defined('BASEPATH') OR exit('No direct script access allowed');
	
/**
* Description of Captcha_Model
*
* @author https://roytuts.com
*/

class Captcha_Model extends CI_Model {
	
	private $login = 'captcha';

	function _create_captcha($cap) {        
		// Save captcha params in database
        $data = array(
            'captcha_time' => $cap['time'],
            'ip_address' => $this->input->ip_address(),
            'word' => $cap['word']
        );
		
        $query = $this->db->insert_string('captcha', $data);
        $this->db->query($query);
        
		return $cap['image'];
    }

    function check_captcha($code) {
        // First, delete old captchas
        $expiration = time() - $this->config->item('captcha_expire'); // 3 mins limit
        
		$this->db->where('captcha_time < ', $expiration)->delete('captcha');
		
        // Then see if a captcha exists:
        $sql = 'SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND captcha_time > ?';
        $binds = array($code, $this->input->ip_address(), $expiration);
        $query = $this->db->query($sql, $binds);
        $row = $query->row();
        
        return $row->count;
    }
	
}

/* End of file captcha_model.php */
/* Location: ./application/models/captcha_model.php */

Route Configuration

Now modify application/config/routes.php file for pointing the default controller class:

$route['default_controller'] = 'captcha_form';

Testing the Application

Now if everything is fine run the application, you will see below output in the browser. At the same time if you look into database table you will see that captcha characters are stored.

codeigniter captcha database
adding captcha to database using codeigniter

Now if you do not put anything and submit the form then error messages displayed:

captcha using codeigniter

If both passwords do not match then you see the error message.

If you enter incorrect captcha then you will see error message.

If everything is entered correctly then you will see below success message:

codeigniter captcha

Source Code

Download

Thanks for reading.

Leave a Reply

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