• Reading time:9 mins read
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

[sociallocker]

download in package

[/sociallocker]


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">&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" />
                </td></tr>
            </table>
        </form>
    </div>
</div>
<?
$sGuestbookBlock = ob_get_clean();

?>
<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta charset="utf-8" />
        <title>PHP guestbook | Dev School</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="https://dev-school.net/php-guestbook/" class="stuts">Back to original tutorial on <span>Dev School</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!