Creating a Diary style PHP Guestbook

Creating a Diary style PHP Guestbook

25 165895
Creating a Diary style PHP Guestbook
PHP guestbook

PHP guestbook tutorial. 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 Ajax). One of important features will spam protection (we can post no more than one record every 10 minutes)!

Live Demo


download in package


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`)

Step 2. PHP

Here are source code of our main file:


// disabling possible warnings
if (version_compare(phpversion(), "5.3.0", ">=")  == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
  error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php'); // including service class to work with database
// get visitor IP
function getVisitorIP() {
    $ip = "";
    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>
    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;
    echo 1;
// drawing last 10 records
$sRecords = getLastRecords();
<div class="container" id="records">
    <div id="col1">
        <h2>Guestbook Records</h2>
        <div id="records_list"><?= $sRecords ?></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 },
                        if (data != '1') {
                          $('#records_list').fadeOut(1000, function () {
                        } else {
                          $('#warning2').fadeIn(2000, function () {
            } else {
              $('#warning1').fadeIn(2000, function () {
        <form onsubmit="submitComment(this); return false;">
                <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">&nbsp;</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" />
$sGuestbookBlock = ob_get_clean();
<!DOCTYPE html>
<html lang="en" >
        <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=""></script>
        <script src=""></script>
        <?= $sGuestbookBlock ?>
            <h2>PHP guestbook</h2>
            <a href="" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>

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:


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:


body {
    font:14px/1.3 Arial,sans-serif;
footer {
    box-shadow: 0 -1px 2px #111111;
footer h2{
    padding:22px 0;
footer a.stuts,a.stuts:visited{
    margin:23px 0 0 110px;
footer .stuts span {
.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;
#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;
    width: 100px;
#records table td.field input[type=submit]:hover {
    background-color: rgba(200, 200, 200, 0.8);
#records_list {
#records_list .record {
    border-top: 1px solid #000000;
    font-size: 13px;
    padding: 10px;
#records_list .record:first-child {
#records_list .record p:first-child {

Live Demo


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!


Design Patterns in PHP

0 114930


  1. 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`)
    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: (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)

  2. I have problem with the database query its telling me that ” database query error” can you please tell me what to do
    thank you

  3. 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.

  4. 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(“”, $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).

  5. 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?

    • Hi Samm,
      This demo doesn’t have the pagination. However this is not a problem to add the pagination.

  6. 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 ( ) 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 :)

  7. 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

  8. 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.

  9. 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.

Leave a Reply to Ed Wylde Cancel reply