Ultimate Guestbook Tutorial: How to build a Guestbook with a honeypot, error checking, IP banning, pagination, e-mail notification and smilies with PHP and mySQL

Meta: April 26th 2008 // PHP

Lets get going on making our honeypot. Before i start with the programming let me introduce to you what a honeypot is. You probably know about spam e-mails; well spam is on websites too. These devils scrape across the internet looking for our webforms and post up their advertisements on just about anything and everything. This is all automated for the spammers, they just hit a button and let their spam dog loose on the internet; which is where we win!

A honeypot is like a trap. We make a hidden text field in our form so that us humans can’t see it in the browser. What good is this you ask? Well the spam bots see everything! They see it as just another spot for them to enter in their advertisements and in thinking so, fill out the field, even though it is graphically hidden. All we then need to do is check if that field was filled in and then handle the request as if it was a spam bot!

What i could do here is make a new table in our database and call it spam bots. Then insert every ip address that gets trapped in this honey pot. Using this method we could then hide the guestbook form from the spammer so that they can never again see the guestbook with their ip address. And when i think of it, i will do this!

But first lets set up our honey pot. Open up form.php.

Find:

<input type="submit" name="submit" value="Sign Guestbook" />

Before it add:

<input type="text" name="message2" />

This is our honeypot! Looks tasty, pity we can’t see it in the browser. Oh well, the spambots will enjoy their feast. Next open up index.php and:

Find:

if(isset($_POST['submit'])){

Replace with:

if(isset($_POST['submit']) && strlen($_POST['message2']) == 0){

This basically checks to see if the honeypot is empty. If it is then there is no spambot, but if there is text in the honeypot then it won’t execute the proper code. So what does it execute? Well nothing. So lets get going on our IP banning solution. We need to make a new table in our database to store the naughty IP addresses:

CREATE TABLE `spam` (
  `id` int(8) NOT NULL AUTO_INCREMENT,
  `ip` varchar(15) collate latin1_general_ci NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `ip` (`ip`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

Execute that sql in your database, like you did before. So we have two columns, an ip address column (which will store the banned ip addresses (derrrrrr)) and a unique identifier column, which would be useful if we wanted to extend the functions of the code.

So before we can ban the spammers, we need to store their details. So lets get going on inserting their IP into the new table in our database.

Open up index.php and find the last curly bracket:

}

After it add:

else if(isset($_POST['submit']) && strlen($_POST['message2']) > 0){
		$postentry = @mysql_query("INSERT INTO `spam` (ip) VALUES ('".$_SERVER['REMOTE_ADDR']."')");
	}

So if a spammer comes along and fills in that field we made, aka honeypot, then their ip gets listed into the database. So lets now use this list of IP’s and block any previous spammers!

Keep index.php open and do:

Below:

include('includes/config.php');

Add:

$query = mysql_query("SELECT * FROM `spam` WHERE `ip`='".$_SERVER['REMOTE_ADDR']."' LIMIT 1");
	$spamip = mysql_num_rows($query);
 
	if($spamip == 0){

Again find the last curly bracket in index.php:

Find:

}

And after it add:

} else {
		$error['spam'] = 'Your IP: '.$_SERVER['REMOTE_ADDR'].' is banned!';
	}

So that your index.php looks like:

<?php
 
	include('includes/config.php');
 
	$query = mysql_query("SELECT * FROM `spam` WHERE `ip`='".$_SERVER['REMOTE_ADDR']."' LIMIT 1");
	$spamip = mysql_num_rows($query);
 
	if($spamip == 0){
		if(isset($_POST['submit']) && strlen($_POST['message2']) > 0){
 
			if(strlen($_POST['name']) == 0){
				$error['name'] = 'Please enter your name';
			}
 
			if(strlen($_POST['email']) == 0){
				$error['email'] = 'Please enter an e-mail address';
			} else {
				if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $_POST['email'])){
					$error['email'] = 'Please enter a correct e-mail address';
				}
			}
 
			if(strlen($_POST['message']) < 2){
				$error['message'] = 'Please enter a message';
			}	
 
			if(!isset($error)){
				$postentry = @mysql_query("INSERT INTO `entries` (name, email, website, message, date, ip) VALUES ('".addslashes($_POST['name'])."', '".addslashes($_POST['email'])."', '".addslashes($_POST['website'])."', '".addslashes($_POST['message'])."', now(), '".$_SERVER['REMOTE_ADDR']."')");
				if($postentry == true){
					unset($_POST);
				}
			}
 
		} else if(isset($_POST['submit']) && strlen($_POST['message2']) == 0){
			$spamentry = @mysql_query("INSERT INTO `spam` (ip) VALUES ('".$_SERVER['REMOTE_ADDR']."')");
		}
	} else {
		$error['spam'] = 'Your IP: '.$_SERVER['REMOTE_ADDR'].' is banned!';
	}
 
	include('templates/skin.php');
?>

If you read the code you would understand that the form is dead, php will not handle any of the requests in terms of error checking or inserting the entry into the database. Exactly what we wanted! We added the error text into our $error array, which will be automatically displayed! Simple.

Alright that’s our honeypot and ipbanning completed. Let’s get going on showing the guestbook entries! finally!

Tags: , , , , , , , ,

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13

Postscript: Leave A Comment // Subscribe (RSS Feed)

Comments About Ultimate Guestbook Tutorial: How to build a Guestbook with a honeypot, error checking, IP banning, pagination, e-mail notification and smilies with PHP and mySQL

// 50 comments so far.

  1. VLADIS // June 02nd 2008

    I make this guestbook.
    It go not me. It always write this errors:

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /3w/wz.cz/m/medvede/5/includes/actions.php on line 3

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /3w/wz.cz/m/medvede/5/includes/functions.php on line 12

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /3w/wz.cz/m/medvede/5/templates/entries.php on line 15

    i have it on http://medvede.wz.cz/5/index.php

    Help me, please.
    thank you

  2. VoiDeT // June 02nd 2008

    Hey Vladis,

    Did you make sure you have created the database correctly?

    Please make sure you have done this, otherwise this error would definitely show up.

  3. VLADIS // June 03rd 2008

    I make this TABLE :

    CREATE TABLE `entries` (
    `id` int(8) NOT NULL auto_increment,
    `name` varchar(255) collate latin1_general_ci NOT NULL,
    `email` varchar(255) collate latin1_general_ci NOT NULL,
    `website` varchar(255) collate latin1_general_ci NOT NULL,
    `message` text collate latin1_general_ci NOT NULL,
    `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
    `ip` varchar(15) collate latin1_general_ci NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

    and this:

    CREATE TABLE `spam` (
    `id` int(8) NOT NULL auto_increment,
    `ip` varchar(15) collate latin1_general_ci NOT NULL,
    PRIMARY KEY (`id`),
    KEY `ip` (`ip`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

    I have in config.php this code:

    And it doesn’t go.

  4. VLADIS // June 03rd 2008

    I have in config.php this code:

    $host = ‘mysql.webzdarma.cz’;
    $username = ‘medvede48′;
    $password = ‘xxx’;
    $dbname = ‘guestbook’; – - I try also entries
    $email = ‘your@email.com’;
    $connect = mysql_connect($host, $username, $password);
    $dbselect = mysql_select_db($dbname);
    $items = 10;

  5. VoiDeT // June 03rd 2008

    Can you please provide me with your ftp details?
    It could be my end, or it could be your end. But i thought i tested this script without any rows in the database. Let me know

  6. VLADIS // June 03rd 2008

    I have it on: photoshopsk.wz.cz
    password: 7754705

    I have files from this tutorial.

  7. VoiDeT // June 04th 2008

    And your username for me to log in please?

  8. VLADIS // June 05th 2008

    (https://www.webzdarma.cz/)
    My username on FTP is : photoshopsk.wz.cz
    and password: 7754705

    (https://www.webzdarma.cz/mysql/index.php)
    And username on mysql server is: photoshopsk
    password:ragp3s

  9. VoiDeT // June 07th 2008

    Those settings do not work.

    I need username, password, and address.

    Otherwise i cannot look for you.

  10. VLADIS // June 07th 2008

    Look you:
    1) http://photoshopsk.wz.cz/1/1.JPG
    2) http://photoshopsk.wz.cz/1/2.JPG
    3) http://photoshopsk.wz.cz/1/3.JPG

    Do you thing this or no?
    If no this, then what you think? What of address?

  11. Linnea // June 09th 2008

    Hi! I just want to say thank you for a wonderful tutorial. I will probably use this at my website when I have finished it, so I can send the link later. Thank you!

  12. VoiDeT // June 09th 2008

    @ Linnea – Thanks alot for your comment. I would love to see your website when you have finished with it!

    @Vladis – Doesn’t work dude. Maybe you have limited the IP range of access?

  13. VLADIS // June 11th 2008

    My action what I make.

    1.) I am download this tutorial: http://www.jotlab.com/wp-content/uploads/2008/04/guestbook.zip

    2.) I give it on a web all. (http://photoshopsk.wz.cz/)

    3.) I am create table :

    CREATE TABLE `entries` (
    `id` int(8) NOT NULL auto_increment,
    `name` varchar(255) collate latin1_general_ci NOT NULL,
    `email` varchar(255) collate latin1_general_ci NOT NULL,
    `website` varchar(255) collate latin1_general_ci NOT NULL,
    `message` text collate latin1_general_ci NOT NULL,
    `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
    `ip` varchar(15) collate latin1_general_ci NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

    and this:

    CREATE TABLE `spam` (
    `id` int(8) NOT NULL auto_increment,
    `ip` varchar(15) collate latin1_general_ci NOT NULL,
    PRIMARY KEY (`id`),
    KEY `ip` (`ip`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

    4.) I chanqe in config.php on it :

    AND IT NO GO.
    You know where is mistake???

  14. Amanda // June 11th 2008

    Hello. I am trying to make a wedding website and want to add a guestbook feature. Everything seemed to be working okay but now I get two big errors.

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/.magdalen/danfrancis/www/attempt/includes/actions.php on line 3

    and

    Fatal error: Call to undefined function: pagination() in /home/.magdalen/danfrancis/www/attempt/templates/skin.php on line 48

    Any clue what is going on? Any help would be great. The site it’s at right now (just testing it out) is: http://www.danfrancisphotography.com/attempt/index.php

    THANKS AGAIN!

  15. Lily // June 11th 2008

    Hello there.

    It doesn’t work at myhomepage.. Can you please tell me, what I’ve done wrong?

    - Lily.

  16. VoiDeT // June 11th 2008

    Hey people,

    I don’t know why you are having these problems. It sounds like an error in the SQL. I am happy to look on your server if you provide me with the correct FTP details or cpanel details.

    I have installed this script from the zip file and it works fine.

    Thank you

  17. Lily // June 12th 2008

    What do you mean with the correct FTP details or cpanel details?

  18. VoiDeT // June 12th 2008

    However you upload the files to your server,
    so i can see what the problem is. Because i cant replicate it

  19. Lily // June 12th 2008

    The only thing I’ve changed is the MySQL otherwise I haven’t touched anything. The same text as Amanda got I have at my page.

  20. VoiDeT // June 12th 2008

    Yep,
    what sql did you change?
    the connection settings?

  21. eHobayyeb // June 22nd 2008

    Amazing!

    Everything works fine.
    I am new PHPier and found many useful tips & tricks!

    Keep it up VoiDeT, I will do all PHP tuts here.

    Thanks
    Mohammad
    hattoon.com

  22. HCF // July 05th 2008

    Hi, awesome tutorial, shows exactly how to use the basics. 2 questions regarding your techniques:
    1. What about using mySQLi instead of the usual mySQL (only PHP5, but way better), since it is faster and more secure.
    2. I guess this was designed for beginner and advanced user, so it would be useful to show a lil bit of object oriented programming, since it makes the source code more accessible and php more flexible.

    Awesome work, greetings from Germany.

  23. VoiDeT // July 05th 2008

    HCF!

    Vielen dank für ihre nette antwort. Du hast auf Englisch geschreiben, so ich werde auf Deutsch antworten. Es freut mich so viel das du die tutorial magst. So danke noch mal. Ich hab noch nicht viele mysqli probiert. Aber ich weiß das es OOP ist. Für dieser tutorial will ich sehr einfach machen, aber vielleicht lern ich MySQLi für meine selber projekte.

    Vielen dank noch mal,

  24. Fredrik // July 07th 2008

    Hi voidet,

    I like the icons you use to identify the country, OS and browser. How did you do that?

  25. VoiDeT // July 07th 2008

    Firestats plugin mate ;)

  26. Akira // July 30th 2008

    Nice guestbook. I like it. :)

  27. Dan Bunyard // August 09th 2008

    Awesome work! I have a guestbook on my existing site but….to put it mildly….it was hacked together to make it work. You have sure a great example here of the things you can do with PHP/MySQL. Keep up the great work, and happy coding!!

  28. Franklyn // August 11th 2008

    I havent read the code in detail but wouldnt it be better to do the error handling client side ?.

  29. VoiDeT // August 12th 2008

    Doing just client side opens you up to attacks.
    This is a server side tutorial anyhow. By just doing client side error checking would be insecure and negligent.

  30. mm // August 24th 2008

    hi – this is really a great tutorial. Im very glad you did this as I was confused about how to add a honeypot.

    listen, do you know how to add an ADMIN page/function to this GB, or is it already there? I was testing mine and managed to ban my own IP! I’m not sure how to manage the database at this point. Any help is appreciated.
    Thanks!

  31. VoiDeT // August 24th 2008

    Hey,

    Simply go into phpmyadmin and delete the entry in the banlist that is associated with your IP address :)

    Thanks for the comments!

  32. Yousha // September 11th 2008

    This form needs CAPTCHA security image.
    GL.

  33. Pick Nick // January 30th 2009

    Just want to see what kind of icon there is for Linux…

  34. VoiDeT // January 30th 2009

    google

    plenty there!

  35. testinr666 // February 16th 2009

    you can delete my posts now, i needed to know if this supported line breaks, which it does.

    thanks

  36. John // February 26th 2009

    Hi:
    Where is the tutorial? Do I have to login to see it or I’m just blind. Thank you.

  37. Martin Murphy // March 05th 2009

    Hi m8 brilliant tutorial. Just wondering any way of putting the guestbook into the layout of your website? I cant quite get it right always goes into the wrong place :S

  38. VoiDeT // March 05th 2009

    Hey Martin!
    Thanks alot for the reply!
    After seeing some bad comments here from some brainless morons, you make me want to write more tutorials!
    I would need to see your page however, then i can give you some feedback on why it isn’t sitting correctly on your page :D Thanks,
    VoiDeT

  39. Norway // March 22nd 2009

    the same problem i got the error

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in C:\AppServ\www\gb\includes\actions.php on line 3

  40. VoiDeT // March 28th 2009

    Norway,
    Try putting some content into your database.
    I really should of built in more tests for this tutorial. However it was a tutorial, not a script give away. I will see if i get some free time soon to patch it up a bit more.

  41. weeman // March 29th 2009

    Hi
    Thanks for the great tutorial!

    I’m just wondering: How do I make a “new line”-character from the form show up as a new line in entries? Just like all entries in this guestbook we’re writing in now show up nicely formatted with new lines.

    new line
    new line
    new line

    instead of
    new line new line new line

  42. VoiDeT // March 30th 2009

    Doesn’t the guestbook show newline characters? I mean doesn’t the text drop down a new line? New line characters are written like “\n” or a return is “\r”. Thanks for the comments Weeman!

  43. Robi Santoso // May 12th 2009

    Great tutorial, thanks a lot for your contributions. I’m newbie in php subject…
    so it’s very useful for me… :)

  44. meg83 // May 20th 2009

    i have the same problem:

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/a9819450/public_html/includes/actions.php on line 3 :!:

  45. Thomas Cherry // May 25th 2009

    I am also having a bit of trouble with setting this guestbook up. I think i’ve tracked the issue to ‘$query’, as this is the one thing that all the errors have in common. Please, i’m new to this. thanks.

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/includes/actions.php on line 3

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/includes/functions.php on line 12

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/templates/entries.php on line 10

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/templates/entries.php on line 15

    the actual code, in order…..

    $spamip = mysql_num_rows($query);

    $rows = mysql_num_rows($query);

    $rows = mysql_num_rows($query);

    while($row = mysql_fetch_array($query)){

  46. Thomas cherry // May 25th 2009

    ok cool, it has to do with the tables??? when i go into myphpadmin i see that there are no tables. could this be the problem….

    guestbook.sql

    CREATE TABLE `entries` (
    `id` int(8) NOT NULL auto_increment,
    `name` varchar(255) collate latin1_general_ci NOT NULL,
    `email` varchar(255) collate latin1_general_ci NOT NULL,
    `website` varchar(255) collate latin1_general_ci NOT NULL,
    `message` text collate latin1_general_ci NOT NULL,
    `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
    `ip` varchar(15) collate latin1_general_ci NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

    CREATE TABLE `spam` (
    `id` int(8) NOT NULL auto_increment,
    `ip` varchar(15) collate latin1_general_ci NOT NULL,
    PRIMARY KEY (`id`),
    KEY `ip` (`ip`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

  47. Thomas cherry // May 25th 2009

    well what do you know. i imported the ‘guestbook.sql’ file into the database using phpmyadmin and bingo, alls well that ends well…. thanks for the tutorial. it really helped me a shit load

  48. Ren // June 15th 2009

    Well, at first I have the problem:-
    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/includes/actions.php on line 3

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/includes/functions.php on line 12

    Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/templates/entries.php on line 10

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/blazesa/public_html/chamvil/guestbook/templates/entries.php on line 15

    But that I change my $dbname to username_guestbook and it works fine. Thanks for the great tutorial. I successfully have created mine.. =)

  49. VoiDeT // June 15th 2009

    I am getting alot of comments about mysql_num_rows errors!
    People, please check that you have the correct database connection settings in order and that your tables have been set up correctly!

  50. Tilak // June 16th 2009

    Hello Friend,….
    Thanx for the nice tutorial its working……
    add more matter like this ….
    we all are very thankful to you..
    Bye

Who Are You?

Your Email Address

Your Website

:D :) :o :eek: :( :lol: :wink: :arrow: :idea: :?: :!: :evil: :p

You can follow any responses to this entry via its RSS comments feed. You may also leave a trackback by clicking this link.