Today I will tell you how to create your own guestbook with spam protection system – math captcha. This will and easy for your members and also good new protection from bots. In our guestbook we will use mySQL to store records.
Here are samples and downloadable package:
Ok, download the source files and lets start coding !
Step 1. SQL
Firstly – we should prepare SQL table to store records of our guestbook. Execute next SQL:
1 | CREATE TABLE `s_guestbook` ( |
2 | `id` INT(11) NOT NULL AUTO_INCREMENT, |
3 | `ip` varchar(16) NOT NULL default '', |
4 | `name` varchar(32) NOT NULL default '', |
5 | `message` text NOT NULL, |
6 | `when` INT(11) NOT NULL, |
8 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
We will be storing IP of sender, his name, message itself, and time of adding post (timestamp)
Step 2. CSS
Here are used CSS styles. Just few styles for our demo page:
css/main.css
1 | body{background:#eee;font-family:Verdana, Helvetica, Arial, sans-serif;margin:0;padding:0} |
2 | .example{background:#FFF;width:625px;font-size:80%;border:1px #000 solid;margin:3.5em auto 2em;padding:1em 2em 2em} |
3 | .post {border:1px #DDD dashed;margin:5px;padding:5px;font-size:11px;width:95%} |
4 | .example form div{margin-bottom:5px;} |
Step 3. PHP
Ok, here are all used PHP file:
index.php
04 | if (version_compare(phpversion(), '5.3.0', '>=') == 1) |
05 | error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); |
07 | error_reporting(E_ALL & ~E_NOTICE); |
09 | require_once('inc/guestbook.inc.php'); |
10 | $oGuestbook = new Guestbook(); |
12 | $sRes = '<h2>You can add your post here</h2>'; |
13 | if ($_POST['post'] != '' && $_POST['name'] != '' && $_POST['captcha'] != '') { |
14 | $iCaptcha = (int)$_POST['captcha']; |
15 | $iCaptchaHash = md5($iCaptcha); |
17 | $iOldCaptchaHash = $_SESSION['captcha_res']; |
19 | if ($iCaptchaHash == $iOldCaptchaHash) { |
20 | $oGuestbook->addPost($_POST['name'], $_POST['post']); |
21 | $sRes = '<h2>Your post successfully posted</h2>'; |
23 | $sRes = '<h2>Captcha incorrect</h2>'; |
27 | list($sQuestion, $iRes) = $oGuestbook->getMathCaptcha(); |
28 | $sPosts = $oGuestbook->getAllPosts(); |
32 | <link rel="stylesheet" href="css/main.css" type="text/css" /> |
34 | <h3><a href="#">PHP Guestbook with using math captcha</a></h3> |
36 | <div style="margin-bottom:10px;"> |
38 | <form method="post" action="index.php"> |
40 | <div><input type="text" name="name" value="" /></div> |
41 | <div>Your guestbook post:</div> |
42 | <div><textarea name="post"></textarea></div> |
45 | <div>Verification (Type what you see):</div> |
46 | <div><input type="text" name="captcha" value="" /></div> |
47 | <div><input type="submit" name="submit" value="Submit" /></div> |
51 | <h4>Other Guestbook posts</h4> |
59 | '{captcha}' => $sQuestion, |
61 | '{guestbook_posts}' => $sPosts, |
63 | echo strtr($sPageCode, $aReplaces); |
This file draw us posting form with math captcha, also it checking typed posted captcha value, and if all fine – then allow to add post. Also, as you noticed, I started using ‘strtr’ function in generation of result HTML code. Very easy to replace keys to values in template file via array of replaces.
inc/guestbook.inc.php
12 | function Guestbook() { |
13 | $this->sDbName = 'DB_NAME'; |
14 | $this->sDbUser = 'DB_USER'; |
15 | $this->sDbPass = 'DB_PASS'; |
19 | function addPost($sNameUnsafe = '', $sPostUnsafe = '') { |
20 | if ($sPostUnsafe != '') { |
21 | $vLink = mysql_connect('localhost', $this->sDbUser, $this->sDbPass); |
22 | mysql_select_db($this->sDbName); |
23 | $sName = mysql_real_escape_string(strip_tags($sNameUnsafe)); |
24 | $sMessage = mysql_real_escape_string(strip_tags($sPostUnsafe)); |
25 | $iVisitorIp = $this->getVisitorIp(); |
26 | if ($sMessage != '' && $iVisitorIp) |
27 | mysql_query("INSERT INTO `s_guestbook` SET `ip`='{$iVisitorIp}', `name`='{$sName}', `message`='{$sMessage}', `when`=UNIX_TIMESTAMP()"); |
33 | function getAllPosts() { |
34 | $vLink = mysql_connect('localhost', $this->sDbUser, $this->sDbPass); |
35 | mysql_select_db($this->sDbName); |
36 | $vRes = mysql_query('SELECT * FROM `s_guestbook` ORDER BY `id` DESC LIMIT 15'); |
40 | while($aMessages = mysql_fetch_array($vRes)) { |
41 | $sWhen = date('H:i:s', $aMessages['when']); |
42 | $sMessages .= '<div class="post">' . $aMessages['name'] . ': ' . $aMessages['message'] . '<span> (' . $sWhen . ')</span></div>'; |
45 | $sMessages = 'DB error, create SQL table before'; |
51 | function getMathCaptcha() { |
52 | $aOps = array('+', '-', '*'); |
56 | $i = array_rand($aOps, 1); |
58 | $sQuestion = "{$iVal1} {$sRandOp} {$iVal2}"; |
59 | $sQuestionEval = "\$iRes = {$iVal1} {$sRandOp} {$iVal2};"; |
63 | $sHashRes = md5($iRes); |
64 | $_SESSION['captcha_res'] = $sHashRes; |
66 | return array($sQuestion, $iRes); |
69 | function getVisitorIp() { |
71 | if ((isset($_SERVER['HTTP_X_FORWARDED_FOR'])) && (! empty($_SERVER['HTTP_X_FORWARDED_FOR']))) { |
72 | $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; |
73 | } elseif ((isset($_SERVER['HTTP_CLIENT_IP'])) && (! empty($_SERVER['HTTP_CLIENT_IP']))) { |
74 | $ip = explode('.',$_SERVER['HTTP_CLIENT_IP']); |
75 | $ip = $ip[3].'.'.$ip[2].'.'.$ip[1].'.'.$ip[0]; |
76 | } elseif ((! isset($_SERVER['HTTP_X_FORWARDED_FOR'])) || (empty($_SERVER['HTTP_X_FORWARDED_FOR']))) { |
77 | if ((! isset($_SERVER['HTTP_CLIENT_IP'])) && (empty($_SERVER['HTTP_CLIENT_IP']))) { |
78 | $ip = $_SERVER['REMOTE_ADDR']; |
This is library class for our Guestbook. It contain several necessary functions: addPost – for adding new posts, getAllPosts – return us last 15 records from database, getMathCaptcha – get math capthca, getVisitorIp – get visitor IP (which we will storing for records)
Conclusion
I hope that made interesting sample today, its contain two interesting ideas – creating Guestbook itself plus Math captcha to protect from bots. Good luck!