Creating Your Own Commenting System from Scratch

Date: 14th Oct 2011 Author: admin 29 Comments
Posted in: AJAX, HTML/CSS, jQuery, MySQL, PHP |Tags: , , , , ,

How to create own commenting system

How to create own commenting system

Today I prepared new interesting article – I will tell how you can create own commenting system (AJAX) for your items (any units at your website) with PHP. For our demonstration – I prepared two SQL tables: first table will keep records of our items. It contain several fields: title, description, time of adding and comments count. Another table will keep records of comments. We will use jQuery too (for better interface behavior). One of features will spam protection (we can post no more than one comment every 10 minutes)!

Live Demo
download in package

Now – download the source files and lets start coding !


Step 1. SQL

We will need to add 2 tables into our database:

CREATE TABLE IF NOT EXISTS `s163_items` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(255) default '',
  `description` text NOT NULL,
  `when` int(11) NOT NULL default '0',
  `comments_count` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `s163_items` (`title`, `description`, `when`, `comments_count`) VALUES
('Item #1', 'Here are you can put description of Item #1', UNIX_TIMESTAMP(), '0'),
('Item #2', 'Here are you can put description of Item #2', UNIX_TIMESTAMP()+1, '0'),
('Item #3', 'Here are you can put description of Item #3', UNIX_TIMESTAMP()+2, '0'),
('Item #4', 'Here are you can put description of Item #4', UNIX_TIMESTAMP()+3, '0'),
('Item #5', 'Here are you can put description of Item #5', UNIX_TIMESTAMP()+4, '0');

CREATE TABLE IF NOT EXISTS `s163_items_cmts` (
  `c_id` int(11) NOT NULL AUTO_INCREMENT ,
  `c_item_id` int(12) NOT NULL default '0',
  `c_ip` varchar(20) default NULL,
  `c_name` varchar(64) default '',
  `c_text` text NOT NULL ,
  `c_when` int(11) NOT NULL default '0',
  PRIMARY KEY (`c_id`),
  KEY `c_item_id` (`c_item_id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;

This is simple tables: first for records of items, second one – for comments

Step 2. PHP

Here are source code of our main file:

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

$sCode = '';
$iItemId = (int)$_GET['id'];
if ($iItemId) { // View item output
    $aItemInfo = $GLOBALS['MySQL']->getRow("SELECT * FROM `s163_items` WHERE `id` = '{$iItemId}'"); // getting info about item from database
    $sCode .= '<h1>'.$aItemInfo['title'].'</h1>';
    $sCode .= '<h3>'.date('F j, Y', $aItemInfo['when']).'</h3>';
    $sCode .= '<h2>Description:</h2>';
    $sCode .= '<h3>'.$aItemInfo['description'].'</h3>';
    $sCode .= '<h3><a href="'.$_SERVER['PHP_SELF'].'">back</a></h3>';

    // drawing last 5 comments
    $sComments = '';
    $aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `s163_items_cmts` WHERE `c_item_id` = '{$iItemId}' ORDER BY `c_when` DESC LIMIT 5");
    foreach ($aComments as $i => $aCmtsInfo) {
        $sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
        $sComments .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
    <p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
    <p>{$aCmtsInfo['c_text']}</p>
</div>
EOF;
    }

    ob_start();
    ?>
    <div class="container" id="comments">
        <h2>Comments</h2>
        <script type="text/javascript">
        function submitComment(e) {
            var sName = $('#name').val();
            var sText = $('#text').val();

            if (sName && sText) {
                $.post('comment.php', { name: sName, text: sText, id: <?= $iItemId ?> },
                    function(data){
                        if (data != '1') {
                          $('#comments_list').fadeOut(1000, function () {
                            $(this).html(data);
                            $(this).fadeIn(1000);
                          });
                        } else {
                          $('#comments_warning2').fadeIn(1000, function () {
                            $(this).fadeOut(1000);
                          });
                        }
                    }
                );
            } else {
              $('#comments_warning1').fadeIn(1000, function () {
                $(this).fadeOut(1000);
              });
            }
        };
        </script>

        <div id="comments_warning1" style="display:none">Don`t forget to fill both fields (Name and Comment)</div>
        <div id="comments_warning2" style="display:none">You can post no more than one comment every 10 minutes (spam protection)</div>
        <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>Comment: </label></td><td class="field"><textarea name="text" id="text"></textarea></td></tr>
                <tr><td class="label">&nbsp;</td><td class="field"><input type="submit" value="Post comment" /></td></tr>
            </table>
        </form>
        <div id="comments_list"><?= $sComments ?></div>
    </div>
    <?
    $sCommentsBlock = ob_get_clean();

} else {
    $sCode .= '<h1>List of items:</h1>';

    $aItems = $GLOBALS['MySQL']->getAll("SELECT * FROM `s163_items` ORDER by `when` ASC"); // taking info about all items from database
    foreach ($aItems as $i => $aItemInfo) {
        $sCode .= '<h2><a href="'.$_SERVER['PHP_SELF'].'?id='.$aItemInfo['id'].'">'.$aItemInfo['title'].' item</a></h2>';
    }
}

?>
<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta charset="utf-8" />
        <title>Creating own commenting system | Script Tutorials</title>

        <link href="css/main.css" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script>
    </head>
    <body>
        <div class="container">
            <?= $sCode ?>
        </div>
        <?= $sCommentsBlock ?>
        <footer>
            <h2>Creating own commenting system</h2>
            <a href="http://www.script-tutorials.com/how-to-create-own-commenting-system/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
        </footer>
    </body>
</html>

By default – this script will draw list of items. Each item have own page. All easy – we will display item title, time of adding (‘when’ field), description, and, most important – our new Comments block. This block contain form of adding new comments, and also will load us last 5 comments. I added my comments in most of places for better understanding. Ok, next PHP file is:

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

$iItemId = (int)$_POST['id']; // obtaining necessary information
$sIp = getVisitorIP();
$sName = $GLOBALS['MySQL']->escape(strip_tags($_POST['name']));
$sText = $GLOBALS['MySQL']->escape(strip_tags($_POST['text']));

if ($sName && $sText) {
    // checking - are you posted any comment recently or not?
    $iOldId = $GLOBALS['MySQL']->getOne("SELECT `c_item_id` FROM `s163_items_cmts` WHERE `c_item_id` = '{$iItemId}' AND `c_ip` = '{$sIp}' AND `c_when` >= UNIX_TIMESTAMP() - 600 LIMIT 1");
    if (! $iOldId) {
        // if all fine - allow to add comment
        $GLOBALS['MySQL']->res("INSERT INTO `s163_items_cmts` SET `c_item_id` = '{$iItemId}', `c_ip` = '{$sIp}', `c_when` = UNIX_TIMESTAMP(), `c_name` = '{$sName}', `c_text` = '{$sText}'");
        $GLOBALS['MySQL']->res("UPDATE `s163_items` SET `comments_count` = `comments_count` + 1 WHERE `id` = '{$iItemId}'");

        // and printing out last 5 comments
        $sOut = '';
        $aComments = $GLOBALS['MySQL']->getAll("SELECT * FROM `s163_items_cmts` WHERE `c_item_id` = '{$iItemId}' ORDER BY `c_when` DESC LIMIT 5");
        foreach ($aComments as $i => $aCmtsInfo) {
            $sWhen = date('F j, Y H:i', $aCmtsInfo['c_when']);
            $sOut .= <<<EOF
<div class="comment" id="{$aCmtsInfo['c_id']}">
    <p>Comment from {$aCmtsInfo['c_name']} <span>({$sWhen})</span>:</p>
    <p>{$aCmtsInfo['c_text']}</p>
</div>
EOF;
        }

        echo $sOut;
        exit;
    }
}
echo 1;
exit;

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;
}

?>

This file will accept POSTed comments and save them into database. In our project we have another one PHP file:

classes/CMySQL.php

This is service class to work with database prepared by me. 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. JS

js/jquery-1.5.2.min.js

This is just jQuery library. Available in package.

Step 4. CSS

Now – all used CSS styles:

css/main.css

*{
    margin:0;
    padding:0;
}

body {
    background-repeat:no-repeat;
    background-color:#bababa;
    background-image: -webkit-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    background-image: -moz-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    background-image: -o-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    background-image: radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    color:#fff;
    font:14px/1.3 Arial,sans-serif;
    min-height:600px;
}

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 {
    border:3px #111 solid;
    color:#000;
    margin:20px auto;
    padding:15px;
    position:relative;
    text-align:center;
    width:500px;

    border-radius:15px;
    -moz-border-radius:15px;
    -webkit-border-radius:15px;
}

#comments form {
    background-color: rgba(255, 255, 255, 0.4);
    margin:10px 0;
    padding:10px;
    text-align:left;
}

#comments table td.label {
    color: #000;
    font-size: 13px;
    padding-right: 3px;
    text-align: right;
    width: 105px;
}

#comments table label {
    color: #000;
    font-size: 16px;
    font-weight: normal;
    vertical-align: middle;
}

#comments table td.field input, #comments table td.field textarea {
    border: 1px solid #96A6C5;
    font-family: Verdana,Arial,sans-serif;
    font-size: 16px;
    margin-top: 2px;
    padding: 6px;
    width: 250px;
}

#comments_list {
    background-color: rgba(255, 255, 255, 0.4);
    margin:10px 0;
    padding:10px;
    text-align:left;
}

#comments_list .comment {
    border-top:1px solid #000;
    padding:10px 0;
}

#comments_list .comment:first-child {
    border-top-width:0px;
}

#comments_list .comment span {
    font-size:11px;
}

Live Demo
download in archive

Conclusion

Today we prepared great commenting system for your website. Sure that this material will useful for your own projects. Good luck in your work!

Enjoyed this Post?

   
   
   
If you enjoyed this article, feel free to share our tutorial with your friends.

29 Comments

    • dekip's Gravatar
    • It’s all nice, but…

      What if i want to put a single comment on my web page? Not five of them. What part of a code to change and how.

    • dekip's Gravatar
    • No, i mean if i want to use only one comment system, not to chose between 5 of “items” and comment one of them.

    • dekip's Gravatar
    • When i looked in your code for the second time i realize that it could be used for much greater things then comments. When i’m finished, i will give you a link.

      Right now, i have a problem to insert a date into “when” with:
      $sql = mysql_query(“INSERT INTO `s163_items` (title, url, description, tagovi, when)
      VALUES(‘$title’,'$url’,'$opis’,'$tagovi’,UNIX_TIMESTAMP()”) or die (mysql_error())
      When is int(11), and that is main problem.

    • lord's Gravatar
    • in Your demo .. when i post comment is still in the comment box !
      it shouldn’t be theire , right ?

    • Amit Yadav's Gravatar
    • This is very nice example that you have shown to implement comment of yourself…:)

      But I want to ask one this, how to remove that limit of 10 minutes after posting one comment no other comment can be posted on that? I tried to look over that code but could not find.

    • abhenav's Gravatar
    • hey,
      how can i moderate the comments i.e. they get posted only when the admin approves them.

    • Elazul's Gravatar
    • nice and awsome work admin , but i was fixed all and run it with my localhost , and i got empty page without items titles oO

    • Gaurav's Gravatar
    • Hello sir I am getting the following errors

      Warning: mysql_connect() [function.mysql-connect]: Access denied for user ‘banksmok_a ‘@’localhost’ (using password: YES) in /home/banksmok/public_html/beauty/classes/CMySQL.php on line 19

      Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link resource in /home/banksmok/public_html/beauty/classes/CMySQL.php on line 22

      Warning: mysql_query() [function.mysql-query]: Access denied for user ‘banksmok’@'localhost’ (using password: NO) in /home/banksmok/public_html/beauty/classes/CMySQL.php on line 24

      Warning: mysql_query() [function.mysql-query]: A link to the server could not be established in /home/banksmok/public_html/beauty/classes/CMySQL.php on line 24

      Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/banksmok/public_html/beauty/classes/CMySQL.php on line 45
      Database query error

    • billy's Gravatar
    • how to i configure the database connection I am not seeing where i should pput my database name

    • billy's Gravatar
    • this error Parse error: syntax error, unexpected $end in C:\xampp\htdocs\comenting\example163\index.php on line 108

    • jinada's Gravatar
    • uhmm sorry for asking, i just have the same problem with bill it says Parse error: syntax error, unexpected $end in C:\wamp\www\example163\index.php on line 108. i did evrything. im just a newbie by the way, thanks!

    • samar's Gravatar
    • Kush's Gravatar
    • Hello Sir, your design for comment box is excellent. I wanted just like this one.

      everything seems fine but when I run the file on my server i.e on localhost, it shows error of unexpected end of line in line 108. I saw from your comment replies that it shouldn’t contain $ on line 108 but there isn’t any symbol of $ in line 108. I went through the code 2 times but there isn’t anything like what the error shows.

      A help would be appreciated. Thank you!

    • vikas's Gravatar
    • Hello , I like the UI part but i need only 1 text holder with submit button .
      I am implementing but the code looks like very complicated and complex .
      could you please sort the code …

    • mohabsi's Gravatar
    • perfect tutorial but i have one question is this secure and how can add a a capacha like this one on you site

      thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

*


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>