Development

Creating a dynamic captcha image with PHP

Sick of my contact form being used as an express way for spammers i set about to make a solution to end the spam to which i was surprised still exists so much in 2019.

I need a custom solution to which would still allow me to use my compressed index.html to keep the lightning quick page load times. I also wanted to avoid adding more JavaScript and using a third-party tool like Google’s reCAPTCHA which can gather data and it actually helps ai improve and get better.  Thats something im not gonna support at this stage thanks.

With help from the code here i made the following function in PHP this code is what I point the cron job at to create the captcha:

 

In short terms it will create an image 60x24 with a random background color, choose 5 random characters from the $selection string, update the database to have this string and put the string onto the image at a random position with white text color.

You will see the function rand() used a lot, rand(0, 100) will return a value anywhere from 0 to 100 and so forth.

A sample of the created captcha is:

SQL file for the MySQL database:

CREATE DATABASE IF NOT EXISTS `captcha` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `captcha`;

CREATE TABLE `captcha` (
  `string` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `captcha` (`string`) VALUES
('T3st');

Now i needed to include a text input in the contact form for the captcha text and alongside it the captcha image we are generating.

Then finally in the form post php file, which checks for correct inputs and sends the actual email i need to add checks for the captcha. To check that text was inputted and to check that its correct this was done like so:

if (!isset($_POST['captcha'])) {
//no captcha text inputted
} else {
//captcha input had text
    $connect = mysqli_connect("localhost", "USERNAME", "PASSWORD", "captcha");
    $result = mysqli_query($connect, "SELECT `string` FROM `captcha` LIMIT 1;");
    while ($row = $result->fetch_assoc()) {
        $string = $row["string"];
    };
    if ($_POST['captcha'] !== $string) {
        //The Captcha input was not the same as what we have stored in the DB
    } else {
        //Captcha was a match with stored string
        //Continue with validation checks for email address, subject and body content.....
        
    }
}

After testing that the validation worked correctly the last step was to point a cron job at the captcha create file.

The interval could have been set at anything from 1 minute through to every 6 hours, it doesn't matter. However for best usage to avoid manual intervention in getting the captcha code I choose every 5 minutes for a new captcha.

Had you set it for several hours long a human could come and crack the captcha code and then use the spam bot for the duration before you got a new captcha generated. With the shorter intervals a new captcha comes along at a shorter timeframe.

Share

Recent Posts

Kennington reservoir drained drone images

A drained and empty Kennington reservoir images from a drone in early July 2024. The…

1 year ago

Merrimu Reservoir drone images

Merrimu Reservoir from drone. Click images to view larger.

1 year ago

FTP getting array of file details such as size using PHP

Using FTP and PHP to get an array of file details such as size and…

2 years ago

Creating Laravel form requests

Creating and using Laravel form requests to create cleaner code, separation and reusability for your…

2 years ago

Improving the default Laravel login and register views

Improving the default Laravel login and register views in such a simple manner but making…

2 years ago

Laravel validation for checking if value exists in the database

Laravel validation for checking if a field value exists in the database. The validation rule…

2 years ago