17-07-2008

PHP Simple PHP captcha script

A very basic PHP / GD based captcha script for stopping those spammers from flooding your guestbooks, mailforms or any other online application susceptible to spam spawning web bots.spam

You can also download the captcha script here

Requires only PHP with GD library installation and a true type font file(.ttf) to create the image

First you make the actual captcha image generating file, and save it as (for instance) 'captcha.php':

To see an example of this script in a live site - have a look at this guestbook. Or just leave a comment below this article

<?php
	session_start();
 
	// generate random number and store in session
 
	$randomnr = rand(1000, 9999);
	$_SESSION['randomnr2'] = md5($randomnr);
 
	//generate image
	$im = imagecreatetruecolor(100, 38);
 
	//colors:
	$white = imagecolorallocate($im, 255, 255, 255);
	$grey = imagecolorallocate($im, 128, 128, 128);
	$black = imagecolorallocate($im, 0, 0, 0);
 
	imagefilledrectangle($im, 0, 0, 200, 35, $black);
 
	//path to font:
 
	$font = '/var/www/font.ttf';
 
	//draw text:
	imagettftext($im, 35, 0, 22, 24, $grey, $font, $randomnr);
 
	imagettftext($im, 35, 0, 15, 26, $white, $font, $randomnr);
 
	// prevent client side  caching
	header("Expires: Wed, 1 Jan 1997 00:00:00 GMT");
	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
	header("Cache-Control: no-store, no-cache, must-revalidate");
	header("Cache-Control: post-check=0, pre-check=0", false);
	header("Pragma: no-cache");
 
	//send image to browser
	header ("Content-type: image/gif");
	imagegif($im);
	imagedestroy($im);
?>

this is an exampe of a form containing the captcha image file captcha.php:

<html>
<head>
	<title>html form with php captcha</title>
</head>
<body>
	<form method="post" action="write.php">
		<input class="input" type="text" name="norobot" />
		<img src="captcha.php" />
		<input type="submit" value="Submit" />
	</form>
</body>
</html>
 

Now all we need is a serverside file that processes the values sent by this form and checks if the captcha test was passed succesfully. In the form above this is refered to by the attribute "action=write.php" and it should contain code something similar to the following:

<?php
	session_start();
	if (md5($_POST['norobot']) == $_SESSION['randomnr2'])	{ 
		// here you  place code to be executed if the captcha test passes
			echo "Hey great , it appears you are not a robot";
	}	else {  
		// here you  place code to be executed if the captcha test fails
			echo "you're a very naughty robot!";
	}
?>

Comments:

26 comments.
Your comment:

»
Kish 30/07/2010, 3:29 pm
Thanks very much for the script.
It helped me a lot.

And how can we add a background image?

Thanks again
gd 25/09/2010, 11:52 am
It's quite easy to do all sorts of adjustments. have a look at the gd library reference for php
<a href="http://www.php.net/manual/en/ref.image.php">http://www.php.net/manual/en/ref.image.php</a>
M. 21/12/2010, 11:32 am
Finally a SIMPLE and clear captcha which you can work on without wasting time. Really a good job. Thanks!
Cees 19/01/2011, 5:28 pm
Cool en doeltreffend! Kun je wel uitleggen waarom je session_start aanroept in write.php? In captcha.php zelf snap ik het wel...
joriso 20/01/2011, 9:13 pm
omdat je $_SESSION['randomnr2']) , uit de sessie global nodig hebt.
Alan 20/03/2011, 3:06 am
First of all - thanks ever o much for kindly sharing this script. It's awesome. I'm a beginner/n00b php user however and I'm having a little bit of difficulty modifying this to fit into another piece of php that I want to use. Instead of saying "if 'norobot' is equal to 'randomnr2' ... echo "great" I want to do the reverse. I want to say this ... "if 'norobot' is NOT equal to "randomnr2" display $error "message" in a <ul> I have defined.

What I'm doing is using a contact form that is using phpmailer and which is set up to detect if a user has ...
A: neglected to enter a name in the name field
B: neglected to enter a valid email address in the email field
C: neglected to leave a comment

then some predefined messages are displayed in the <ul> I'm trying to incorporate this captcha script and have it so that if there was an error with the captcha then another predefined messages will displayed int he same <ul>. Here's is the code I am using ....

<colde>if (strlen($name) < 2) {
$error['name'] = "Please enter your name";
}

if (!preg_match('/^[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $email)) {
$error['email'] = "Please enter a valid email address";
}

if (strlen($comments) < 3) {
$error['comments'] = "Please leave a comment";
}

if (md5($_POST['captcha']) != $_SESSION['randomnr2']) {
$error['captcha'] = "CAPTCHA error. Please try again";
}
</code>

Could somebody tell me if this is correct? I'd really appreciate it :)

Alan
test 04/08/2011, 12:31 am
setset
mike foskett 01/04/2011, 12:13 am
Thanks for the script fella.
Very easy to implement too, excellent.

Implemented it on the comment form at the bottom of this page:
http://websemantics.co.uk/resources/useful_css_snippets/

I've added a credit at the bottom of the form linking back to here too.
gbg 13/04/2011, 8:41 pm
nice work!
Louis 30/04/2011, 3:45 am
Amazing website!
W-Mast 19/05/2011, 5:29 pm
Do not forget following:
$_SESSION['randomnr2']=null;
after checking the Captcha input.



ayger 01/06/2011, 4:44 pm
in my form its not working
I added the write.php script in this :


<html>
<head>
<title>Formulier verwerken AygerVillas</title>
</head>
<body>
U vulde in:<br />


<table>
<?php

require_once('secure/contact.php');
//Ga er vanuit dat het formulier correct is ingevuld
$correct = true;



//Sla de waarde van het veld naam op in een variabele
$naam = $_POST['name'];
if($naam != "" && !strpos($naam, "<")){
echo "<tr><td>Achternaam: </td><td>" . $naam . "</td></tr>n";
}else{
echo "<tr><td>Achternaam: </td><td><em>U heeft geen naam ingevuld!</em></td></tr>n";
$correct = false; //Toch een foute waarde, onthou dit!
}

//Sla de waarde van het veld email op in een variabele
$email = $_POST['email'] ;
if($email != "" && !strpos($email, "<") && strpos($email, "@") && strpos($email, ".") && strlen($email) > 5){
echo "<tr><td>Email: </td><td>" . $email . "</td></tr>n";
}else{
echo "<tr><td>Email: </td><td><em>Vul een geldig email adres in!</em></td></tr>n";
$correct = false; //Toch een foute waarde, onthou dit!
}

//Sla de waarde van het veld reactie op in een variabele
$reactie = $_POST['reactie'] ;
if($reactie != "" && !strpos($reactie, "<")){
echo "<tr><td>Bericht: </td><td>" . $reactie . "</td></tr>n";
}else{
echo "<tr><td>Bericht: </td><td><em>U heeft niets ingevuld bij bericht!</em></td></tr>n";
$correct = false; //Toch een foute waarde, onthou dit!
}

?>

</table>
<?php
//Was alles correct ingevuld?
if($correct){
//maak een verbinding met de database
$link = mysql_connect($mysql_host, $mysql_user, $mysql_pass);
//selecteer de juiste database
mysql_select_db("reacties", $link);

//kijk of een persoon al bestaat
$sql = "SELECT id FROM personen WHERE naam = '" . $naam . "' AND email = '" . $email . "'";
//echo $sql . "<br />n";
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0){
//vraag de id van een bestaand persoon op
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$persoon_id = $row['id'];
} else {
//voeg de naam en email toe in de tabel personen
$sql = "INSERT INTO personen(naam, email) VALUES ('" . $naam . "', '" . $email . "')";
//echo $sql . "<br />n";
mysql_query($sql);
//vraag de id van de nieuwe persoon op
$persoon_id = mysql_insert_id();
}

//voeg de reactie toe in de tabel reacties. Gebruik de id van de zojuist toegevoegde persoon
$sql = "INSERT INTO reacties(persoon_id, reactie, datum) VALUES (" . $persoon_id . ", '" . $reactie . "', NOW())";
//echo $sql . "<br />n";
mysql_query($sql);

//sluit de database
mysql_close($mysqlLink);
echo "<br /><br />Bovenstaande informatie is opgeslagen!<br />n";
}else{
echo "<br /><br />Er is een foute waarde ingevoerd, <a href="javascript:history.back();">ga terug</a>.<br />n";
}
?>
<?php
session_start();
if (md5($_POST['norobot']) == $_SESSION['randomnr2'])
{
// here you place code to be executed if the captcha test passes
echo "de code is juist ingevuld";
} else {
// here you place code to be executed if the captcha test fails
echo "U heeft een verkeerde code ingevuld!";
}
?>
</body>
</html>
test 12/09/2011, 6:11 pm
test
test 28/06/2011, 10:06 am
test
Tosheen 21/07/2011, 2:28 pm
Great script, Thank you!
OneQuote.Info 25/07/2011, 5:41 pm
Great script... Just follow the instruction, abracadabra you're form have a captcha...

Thanks!
Autopten Cheap Cars 01/09/2011, 12:33 am
Many thanks Hardcode.nl webmaster. It was easy to setup and implement in my site. Recommended. I'm using it in many of my pages.
test 22/09/2011, 4:29 pm
test
Uri 11/11/2011, 3:58 pm
10x
d 10/01/2012, 3:03 am
f
Luis 14/11/2011, 3:11 pm
Simples e bem feito
ayberk canturk 26/11/2011, 3:51 pm
Can somebody tell me whats wrong with my php code? (write.php)

<?php
header("Content-Type: text/html; charset=ISO-8859-9");
session_start();
if (md5($_POST['norobot']) == $_SESSION['randomnr2']) {

$field_name = $_POST['field_name'];
$field_email = $_POST['field_email'];
$field_tel = $_POST['field_tel'];
$field_message = $_POST['field_message'];
$radio_button = $_POST['radio_button'];
$drop_down_item = $_POST['drop_down_item'];


$mail_to = 'xxxx@gmail.com';
$subject = 'contact form: '.$drop_down_item;

$body_message = 'Full Name '.$field_name."n";
$body_message .= 'E-mail: '.$field_email."n";
$body_message .= 'Telephone: '.$field_tel."n";
$body_message .= "Feedback: ".$radio_button."n";
$body_message .= 'Message: '.$field_message;

$headers = 'From: '.$field_email."rn";
$headers .= 'Reply-To: '.$field_email."rn";

$mail_status = mail($mail_to, $subject, $body_message, $headers);

if ($mail_status) { ?>
<script language="javascript" type="text/javascript">
alert('Success.');
history.back(1);
</script>
<?php
}
else { ?>
<script language="javascript" type="text/javascript">
alert('error.');
history.back(1);
</script>
<?php
}

else {
echo "wrong code!";
}

?>


waiting for comment and ayberkc@hotmail.com is my e-mail.
N00by 29/11/2011, 6:20 pm
I agree, simple scripts and easy to adjust, a good starting point.

Thanks for the post.
piyush 29/12/2011, 10:48 am
test
Yaseer 31/12/2011, 2:17 pm
I m very new to php.

I use this but captcha not showing image?

Thx in Advance

Regrds
sanjeev 11/01/2012, 2:14 am
very nice.

 

[x]