Most webdesigners have to deal with spam at some point.
I have tried reCaptcha on several websites and noticed it can actually attrach spam in some cases so made my own mini-version.

The idea is simple:

  • Generate a string of random text.
  • Get the user to copy the text.
  • Check if the two match.
  • If so, proceed. If not, show an error.


A demo contact form:
Contact form with Captcha

A simple comment form

Below is a very simple comment form found on many websites and blogs.
I have added a captcha image and input field to help keep those pesky robots at bay!
Some basic styling is included to make it look nice.

<style type="text/css">
	body{ background:url(./elevate-local.png) top right no-repeat;width:450px;
	margin:25px auto 0 auto;font-family:Verdana, Geneva, sans-serif; color:#666;}
	label{clear:left; float:left; width:120px; padding-right:6px;}
	input, textarea{float:left; width:200px; border:1px solid #CCC; padding:2px; color:#999}
	form img{float:left; margin:8px 6px 0 0;}
	h2{color:#CDCDCD; margin-bottom:15px; border-bottom:1px solid #CDCDCD}
	.row{height:30px;}
	.row2{height:77px;}
	.captcha{width:120px}
	#send{clear:left; width:75px; margin:15px 0 0 125px; border:1px solid #36489c}
	#send:hover{border:1px solid #e91d58; cursor:pointer}
	#sent{width:200px; background:#096; display:block; text-align:center; margin:auto auto;
	padding:10px; border:1px solid #CDCDCD; color:#FFF; font-weight:bold}
</style>

<form action="./send-message.php?message=sent" method="post">
    <div class="row"><label for="name">Name:</label>
    <input type="text" name="name" id="name" maxlength="30" /></div>

    <div class="row"><label for="email">Email:</label>
    <input type="text" name="email" id="email" maxlength="30" /></div>

    <div class="row2"><label for="message">Message:</label>
    <textarea name="message" id="message" rows="4" cols="20"></textarea></div>

    <div class="row"><label for="captcha">Captcha:</label>
    <img src="captcha.php" alt="captcha" /> &amp;nbsp;
    <input name="captcha" id="captcha" type="text" class="captcha" /></div>

    <div class="row"><input type="submit" value="Send" id="send" /></div>
</form>

Generate a captcha image

Now we have our form, we need to create some code to generate the captcha string and show it as an image. So we need to make “captcha.php”.

session_start(); // Start a session to store the captcha
$randomstring = md5(microtime()); // Generate a sudo-random string
$resultstring = substr($randomstring,0,5); // Trim it to 5 characters
$captchaimage = imagecreatefrompng("captcha.png"); // Create a background from existing image
$textcolor = imagecolorallocate($captchaimage,19,114,145); // Set the text color

imagestring($captchaimage, 5, 15, 4, $resultstring, $textcolor);// Draw our random string

$_SESSION['captcha'] = $resultstring; // Store the correct captcha in a session variable

header("Content-type: image/png"); // Set the file header
imagejpeg($captchaimage); // Output image to browser

Handling the data

Now the form is ready and the user has a session cookie with our captcha code.
Next we need to check all information entered is correct and, most importantly, they are not a robot!
The email will be sent if all the entered information was valid or show errors based on what went wrong.

if ($_POST && $_GET['message'] == 'sent') { // If the form was sent,
	$error = 0; // Set a simple error flag

	if($_REQUEST['name'] == '') { // Was a name entered?
		echo 'Please input your name<br />';
		$error = 1;
	}
	if($_REQUEST['email'] == '' || !filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL)) { // Is the email address valid?
		echo 'Please input a valid email address<br />';
		$error = 1;
	}
	if($_REQUEST['message'] == '') { // Was a message entered?
		echo 'Please input a message<br />';
		$error = 1;
	}
	if($_REQUEST['captcha'] == '' || $_REQUEST['captcha'] != $_SESSION['captcha']) { // Is the captcha is valid?
		echo 'Please input a valid captcha<br />';
		$error = 1;
	}

	if($error == 0) { // If there were no errors, send the email
		$to = 'mradamdavies@twitter.com'; // Your email address
		$subject = 'Comment Form'; // Email subject line
		$message = strip_tags(addslashes($_REQUEST['message'])); // The message
		$from = strip_tags(addslashes($_REQUEST['email'])); // The senders email
		$headers = 'From: '.$from; // Email header
		mail($to,$subject,$message,$headers); // Send the compiled email
		echo '<span id="sent">Mail Sent.</span>';
		exit();
	}
}

Wrapping up

There are of course a few considerations.
This example assumes your server is running PHP version 5+ to use the FILTER_VALIDATE_EMAIL function and can send PHP mail.
The above code is aimed at stopping spam and not other attacks, such as SQL injection.
I’m sure you can do better than a bunch of if statements, but it’s a nice starting point.