PHP guestbook
Today I prepared new interesting tutorial – I will tell how you can create ajax PHP guestbook with own unique design. Our records will be saved into SQL database. This table will contain next info: name of sender, email, guestbook record, date-time of record and ip of sender. Of course, we will use jQuery too (to make it ajaxy). One of important features will spam protection (we can post no more than one record every 10 minutes)!
Live Demo
Now – download the source files and lets start coding !
Step 1. SQL
We need to add one table to our database (to store our records):
CREATE TABLE IF NOT EXISTS `s178_guestbook` ( `id` int(10) unsigned NOT NULL auto_increment, `name` varchar(255) default '', `email` varchar(255) default '', `description` varchar(255) default '', `when` int(11) NOT NULL default '0', `ip` varchar(20) default NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Step 2. PHP
Here are source code of our main file:
guestbook.php
<?php // disabling possible warnings if (version_compare(phpversion(), "5.3.0", ">=") == 1) error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); else error_reporting(E_ALL & ~E_NOTICE); require_once('classes/CMySQL.php'); // including service class to work with database // get visitor IP function getVisitorIP() { $ip = "0.0.0.0"; if( ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) && ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } elseif( ( isset( $_SERVER['HTTP_CLIENT_IP'])) && (!empty($_SERVER['HTTP_CLIENT_IP'] ) ) ) { $ip = explode(".",$_SERVER['HTTP_CLIENT_IP']); $ip = $ip[3].".".$ip[2].".".$ip[1].".".$ip[0]; } elseif((!isset( $_SERVER['HTTP_X_FORWARDED_FOR'])) || (empty($_SERVER['HTTP_X_FORWARDED_FOR']))) { if ((!isset( $_SERVER['HTTP_CLIENT_IP'])) && (empty($_SERVER['HTTP_CLIENT_IP']))) { $ip = $_SERVER['REMOTE_ADDR']; } } return $ip; } // get last guestbook records function getLastRecords($iLimit = 3) { $sRecords = ''; $aRecords = $GLOBALS['MySQL']->getAll("SELECT * FROM `s178_guestbook` ORDER BY `id` DESC LIMIT {$iLimit}"); foreach ($aRecords as $i => $aInfo) { $sWhen = date('F j, Y H:i', $aInfo['when']); $sRecords .= <<<EOF <div class="record" id="{$aInfo['id']}"> <p>Record from {$aInfo['name']} <span>({$sWhen})</span>:</p> <p>{$aInfo['description']}</p> </div> EOF; } return $sRecords; } if ($_POST) { // accepting new records $sIp = getVisitorIP(); $sName = $GLOBALS['MySQL']->escape(strip_tags($_POST['name'])); $sEmail = $GLOBALS['MySQL']->escape(strip_tags($_POST['name'])); $sDesc = $GLOBALS['MySQL']->escape(strip_tags($_POST['text'])); if ($sName && $sEmail && $sDesc && $sIp) { // spam protection $iOldId = $GLOBALS['MySQL']->getOne("SELECT `id` FROM `s178_guestbook` WHERE `ip` = '{$sIp}' AND `when` >= UNIX_TIMESTAMP() - 600 LIMIT 1"); if (! $iOldId) { // allow to add comment $GLOBALS['MySQL']->res("INSERT INTO `s178_guestbook` SET `name` = '{$sName}', `email` = '{$sEmail}', `description` = '{$sDesc}', `when` = UNIX_TIMESTAMP(), `ip` = '{$sIp}'"); // drawing last 10 records $sOut = getLastRecords(); echo $sOut; exit; } } echo 1; exit; } // drawing last 10 records $sRecords = getLastRecords(); ob_start(); ?> <div class="container" id="records"> <div id="col1"> <h2>Guestbook Records</h2> <div id="records_list"><?= $sRecords ?></div> </div> <div id="col2"> <h2>Add your record here</h2> <script type="text/javascript"> function submitComment(e) { var name = $('#name').val(); var email = $('#email').val(); var text = $('#text').val(); if (name && email && text) { $.post('guestbook.php', { 'name': name, 'email': email, 'text': text }, function(data){ if (data != '1') { $('#records_list').fadeOut(1000, function () { $(this).html(data); $(this).fadeIn(1000); }); } else { $('#warning2').fadeIn(2000, function () { $(this).fadeOut(2000); }); } } ); } else { $('#warning1').fadeIn(2000, function () { $(this).fadeOut(2000); }); } }; </script> <form onsubmit="submitComment(this); return false;"> <table> <tr><td class="label"><label>Your name: </label></td><td class="field"><input type="text" value="" title="Please enter your name" id="name" /></td></tr> <tr><td class="label"><label>Your email: </label></td><td class="field"><input type="text" value="" title="Please enter your email" id="email" /></td></tr> <tr><td class="label"><label>Comment: </label></td><td class="field"><textarea name="text" id="text" maxlength="255"></textarea></td></tr> <tr><td class="label"> </td><td class="field"> <div id="warning1" style="display:none">Don`t forget to fill all required fields</div> <div id="warning2" style="display:none">You can post no more than one comment every 10 minutes (spam protection)</div> <input type="submit" value="Submit" /> </td></tr> </table> </form> </div> </div> <? $sGuestbookBlock = ob_get_clean(); ?> <!DOCTYPE html> <html lang="en" > <head> <meta charset="utf-8" /> <title>PHP guestbook | Script Tutorials</title> <link href="css/main.css" rel="stylesheet" type="text/css" /> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <script src="http://code.jquery.com/jquery-latest.min.js"></script> </head> <body> <?= $sGuestbookBlock ?> <footer> <h2>PHP guestbook</h2> <a href="http://script-tutorials.com/php-guestbook/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a> </footer> </body> </html>
When we open this page we will see book, at left side we will draw list of last three records, at right – form of posting new records. When we submitting form – script sending POST data (to same php page), script saving this data to database, and returning us list of fresh 3 records. Then, via fading effect we draw returned data at left column. All code contains comments – read it for better understanding code. Ok, next PHP file is:
classes/CMySQL.php
This is my own service class to work with database. This is nice class which you can use too. Database connection details located in this class in few variables, sure that you will able to configure this to your database. I don`t will publish its sources – this is not necessary for now. Available in package.
Step 3. CSS
Now – all used CSS styles:
css/main.css
*{ margin:0; padding:0; } body { background-color:#fff; color:#fff; font:14px/1.3 Arial,sans-serif; } footer { background-color:#212121; bottom:0; box-shadow: 0 -1px 2px #111111; display:block; height:70px; left:0; position:fixed; width:100%; z-index:100; } footer h2{ font-size:22px; font-weight:normal; left:50%; margin-left:-400px; padding:22px 0; position:absolute; width:540px; } footer a.stuts,a.stuts:visited{ border:none; text-decoration:none; color:#fcfcfc; font-size:14px; left:50%; line-height:31px; margin:23px 0 0 110px; position:absolute; top:0; } footer .stuts span { font-size:22px; font-weight:bold; margin-left:5px; } .container { background: transparent url(../images/book_open.jpg) no-repeat top center ; color: #000000; height: 600px; margin: 20px auto; overflow: hidden; padding: 35px 100px; position: relative; width: 600px; } #col1, #col2 { float: left; margin: 0 10px; overflow: hidden; text-align: center; width: 280px; } #col1 { -webkit-transform: rotate(3deg); -moz-transform: rotate(3deg); -ms-transform: rotate(3deg); -o-transform: rotate(3deg); } #records form { margin:10px 0; padding:10px; text-align:left; } #records table td.label { color: #000; font-size: 13px; padding-right: 3px; text-align: right; } #records table label { font-size: 12px; vertical-align: middle; } #records table td.field input, #records table td.field textarea { background-color: rgba(255, 255, 255, 0.4); border: 0px solid #96A6C5; font-family: Verdana,Arial,sans-serif; font-size: 13px; margin-top: 2px; padding: 6px; width: 190px; } #records table td.field input[type=submit] { background-color: rgba(200, 200, 200, 0.4); cursor: pointer; float:right; width: 100px; } #records table td.field input[type=submit]:hover { background-color: rgba(200, 200, 200, 0.8); } #records_list { text-align:left; } #records_list .record { border-top: 1px solid #000000; font-size: 13px; padding: 10px; } #records_list .record:first-child { border-top-width:0px; } #records_list .record p:first-child { font-weight:bold; font-size:11px; }
Live Demo
Conclusion
Today we have prepared great PHP guestbook for your website. Sure that this material will be useful for your own projects. Good luck in your work!
Hi there,
I love this gurestbook, however it’s not clear how one would actually get this to work on a website eg.
You wrote: Step 1. SQL – We need to add one table to our database (to store our records):
Question: What’s the name of the database?
You wrote: CREATE TABLE IF NOT EXISTS `s178_guestbook` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(255) default ”,
`email` varchar(255) default ”,
`description` varchar(255) default ”,
`when` int(11) NOT NULL default ’0′,
`ip` varchar(20) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Question: Which CHARSET=utf8 do you use?
Question: Where are all these files placed on the server to make it work? Should they be placed directly within Public_html or should a folder be created withing Public_html to hold the files? if so, What should the folder be called?
Should all this code be placed inside an html document? or would you just created a link from say the homepage (index.html) to the guestbook.php? eg a link on my homepage would be: http://www.falseidols.com/guestbook.php (assuming the file/s were in the root directory.
Any more information you can give me about this would be appreciated.
Hello Ed Wylde,
You can use any database which you’ve got. It can be any current database of your active script, or, you always can create a new separated database and use it for this script. As you wish.
Also, it doesn’t matter where exactly you will host all sources files, if you like to keep them in public_html of your server – do it, or you always can create own subfolder in your public_html directory. Just keep proper structure (of relationships between main file and other folders)
I have problem with the database query its telling me that ” database query error” can you please tell me what to do
thank you
Hi Mido,
Please make sure that you linked your database properly in classes/CMySQL.php
not control for email in guestbook sorry for my english
Hello Paola,
What do you mean? All emails (by guests) should be stored in database
Hi
this guestbook is amazing however
can I add a captcha or block IPs? I having a lot of spam posts
Thank you
Yes, I agree, spam is annoying. I can recommend you to install Google’s reCaptcha or custom logical captcha to prevent spam.
Hi admin, im having the same problem as mido, it is coming up as ‘database query error’. Im new to this so I’m not sure where I am going wrong. Is my ip address or DbName the issue here?
// constructor
function CMySQL() {
$this->sDbName = ‘guestbook’;
$this->sDbUser = ‘desgrp5′;
$this->sDbPass = ‘D43eHK7M’;
// create db link
$this->vLink = mysql_connect(“193.61.148.95″, $this->sDbUser, $this->sDbPass);
//select the database
mysql_select_db($this->sDbName, $this->vLink);
mysql_query(“SET names UTF8″);
}
Hello Kieran,
This is strange, because your connection params look correct. I can recommend you to display an actual SQL error on the screen. Please pay attention on
function error,
as you can see, by default, it prints only a short text: ‘Database query error’, because of: echo $text; exit;
but, you can add $sSqlQuery param to echo too (to see an exact problem you have).
So what we must to do next?
If you need to expand it – you just increase this digit.
He
I try to run the guestbook but got this error in guestbook.php “Fatal error: Call to a member function getAll() on a non-object in ../example178/guestbook.php on line 29″
I think the table in the database is ok.
Can you help me?
Thanks
Hello Jisafu,
Please make sure that you use correct DB details in CMySQL.php
How this the pagination work? how do you view previous posts?
Hi Samm,
This demo doesn’t have the pagination. However this is not a problem to add the pagination.
hello, well, thank you so much for this amazing guestbook, i really love it, but i have a problem, as u see in my website ( ilyassm.com/sync/guest/ ) the records can’t be stored on the database, i type a comment, but it doesn’t work, try it for me please ;)
thank you :)
Hi,
It works even on your website, there is one thing – you should open ‘index.php’ by your URL
FANTASTIC GUESTBOOK – BUT WHERE CAN I SEE MORE THAN 3 COMMENTS
Hi Jorgen,
You can refer to the function getLastRecords($iLimit = 3)
when i install and run it it saves my data and simultaneously displays on page but after refreshing the page all the data gets cleared from the page but remains in database. how to resolve this problem.
Thankyou for your nice script
Hi Olly,
Try to clear your browser caches
Hello this looks like a great app but having a little trouble implementing. I was able to create the SQL database and copied/pasted the above scripts however could not find the classes/CMySQL.php script nor the image files for the book? There is comment near the top of the page,…’Now – download the source files and lets start coding !’,…however cannot find a download option that may contain the required files. I noticed another training session had a CMySQL.php script which I may try to use but still need the book image file. The information is probably right in front of me but can’t see it; perhaps I’ve been working on this too long (LOL).
Thank you
Hi Terry, this file was developed by me long ago, and you can find it in our package. There was no any reason to publish this file in our tutorial.
Awesome programming demonstration enhanced by using a practical and very creative example. A great introduction to creating live webpages using PHP, MySQL, and CSS. I have much to learn but this was certainly a great start.
Thank you for sharing.