Sorry about my last post, I was misinformed about the security of the $_SESSION superglobal. This time we’re going to make a user validation box to make sure that it is a human sending the contact request (not a spambot). This is the most reliable way to prevent spam.
To follow this tutorial, you’ll need a free font (make sure its FREE, not free for personal use) to use in our validation image. There probably aren’t going to be many spambots with image-to-text capabilities, but try to find a font that isn’t too easily interpreted by a computer. I used Acidic, which is fairly readable for a human but very difficult for a computer to interpret.
We’re going to start out by making our form, just with simple HTML. In the form we’re going to have a text box for the contacter’s email, a textarea for the message, a validation image and text box, and submit button.
<form id="contact" name="contact" method="post" action="contact.php">
<h2>Contact Me</h2>
Email:
<input type="text" name="contact_email" id="contact_email" />
<textarea name="contact_text" id="contact_text">
</textarea>
<img src="valid_image.php" width="100" height="30" alt="Type this text in the box below."/>
<input type="text" name="validate" />
<input type="submit" id="contact_submit" name="contact_submit" value="Send" />
</form>
As you can see, the image is actually a PHP file, valid_image.php. In this file, we are going to come up with a random validation string, store it in a session variable, and draw an image with the text in the font we chose. For this to work, you need to give the imagettftext() a relative path to the font from where valid_image.php is saved. If it is the same directory, than just “yourfont.ttf” will do.
<?php
session_start();
header("Content-type: image/png");
// make the random 5-character string
$rand = "";
for ($i=0;$i<5;$i++) {
$rand .= chr(rand(97,122));
}
$_SESSION['validate'] = $rand;
$width = 100;
$height = 30;
$image = @imagecreate($width,$height);
$bgcolor = imagecolorallocate($image,255,255,255); // put your background color here
$textcolor = imagecolorallocate($image,0,0,0); // put your text color here
imagefilledrectangle($image,0,0,$width,$height,$bgcolor);
imagettftext($image,25,0,0,$height,$textcolor,"acidic.ttf",$rand);
imagepng($image);
imagedestroy($image);
?>
So now we have an image with the string, and a session variable holding the string. Now, when the request is sent to contact.php, we will compare the session variable to the value given in the form. If they are the same, then the contacter is a human that could read the image.
Your contact.php should be saved in the same directory as your form (or you could edit the action attribute of the form), and it should look like this:
<?php
session_start();
if (!empty($_POST['validate'])) {
if ($_POST['validate'] == $_SESSION['validate']) {
unset($_SESSION['validate']);
if (!empty($_POST['contact_text']) && !empty($_POST['contact_email'])) {
$to = 'webmaster@example.com';
$subject = 'Contact Request from '.$_POST['contact_email'];
$message = $_POST['contact_text'];
$headers = 'From: '.$_POST['contact_email']." rn" .
'Reply-To: '.$_POST['contact_email']."rn" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
echo "Thanks for contacting me!";
} else {
echo "Please enter both your email and a message.";
}
} else {
echo "Your validation code was incorrect."
}
}
?>
Steve Love gave me a good tip to unset the session variable after use so that it could not be reused. Thanks!
This tutorial was mainly about the validation technique, but if you want to make this form asynchronous, you can follow the last few steps of my last tutorial, to implement the jQuery and AJAX.
Thanks for reading!