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"> </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!

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.
Hello Dekip,
Then, open your ‘comment.php’ and change ‘LIMIT 5′ at line 25 to LIMIT 1
No, i mean if i want to use only one comment system, not to chose between 5 of “items” and comment one of them.
Ah, I see, then, separate our code into 2 parts, remove half (where I am working with all these items), and keep only most important – comments itself.
And, hardcode as item id = 1 as example
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.
Please check your syntax, possible you forgot bracket after UNIX_TIMESTAMP()
in Your demo .. when i post comment is still in the comment box !
it shouldn’t be theire , right ?
Hello Lord,
Why? I didn’t add functionality to remove text from comment box after it send. You can add it of course, you can add
$(‘#text’).val(”);
directly after:
$(this).html(data);
$(this).fadeIn(1000);
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.
Hi Amit Yadav,
Please pay attention to ’600′ in code (this is 600 seconds, or 10 mins)
hey,
how can i moderate the comments i.e. they get posted only when the admin approves them.
Hello abhenav,
In your case you should create a new one field to table with comments (s163_items_cmts) – ‘status’.
It can be smallint field (we have to keep here 2 statuses – active and pending (or, 0 and 1)).
Then, during adding new comments – set ‘pending’ status, finally – create some admin panel page to approve new (pending) comments.
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
Hello Elazul,
Please make sure that you adjusted your DB connection in this file: classes/CMySQL.php
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
Hello Gaurav,
Please make sure that you adjusted your DB connection in this file: classes/CMySQL.php
how to i configure the database connection I am not seeing where i should pput my database name
Hello billy,
It is in this file: classes/CMySQL.php, look at the top of code
this error Parse error: syntax error, unexpected $end in C:\xampp\htdocs\comenting\example163\index.php on line 108
Hi billy again,
please recheck your index.php file. It doesn’t contain any $ symbol on line 108
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!
Hi jinada,
I’ve just rechecked demo on localhost, it works well. How do you run this demo? On localhost?
In your case you should open it as: http://localhost/example163/index.php
is it the same url you tried?
COOL C.S .:-) so u created ur comment system in which i m writing ryt now using this code?
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!
Hi Kush,
Please read my comment which I wrote for ‘jinada’
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 …
Hello vikas,
There are only two pretty small PHP files where you can make changes.
If you want to remove ‘Your name’ field here, you can just search for ‘name’ in both files, and remove all located instances where it is used. It should be difficult.
perfect tutorial but i have one question is this secure and how can add a a capacha like this one on you site
thanks
The issue of security is up to you only.
Right now it is safe about SQL injections. But if you are going to use it on your live website, yes, it would be useful to implement here extra protections (as example – a captcha, and maybe a protection of often submits, maybe something else). How exactly you can add a captcha? It depends only on a captcha you want to implement. They can have different realizations.