Enhanced comments system – PHP, mySQL, jQuery and AJAX

facebookThis was long due but finally it’s here. I present to you the enhanced version of the Facebook comments system (which was published a month ago). A lot of readers asked for this version, so how can I say no to them. Without wasting any time let’s first check out what this system has to offer.

This version of the comments system has the following features.

  • Only logged-in users can post comment
  • User authentication via Facebook
  • Comments are now stored in the database
  • Ability for the user to delete the comments posted by them
  • User profile images via Gravatar
  • Completely AJAX based
  • Protection against CSRF (Cross site request forgery)
  • Secure sessions as sessions are stored in the database


Seems promising? It surely is. Here are the important links. Demo or Download.


Impressed with the demo? Now, let’s explore the system from the scratch. To begin with, the SQL structure is shown below.

  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `comment` varchar(500) COLLATE utf8_bin NOT NULL,
  `m_id` int(10) unsigned NOT NULL,
  `datetime` datetime NOT NULL,
  PRIMARY KEY (`id`)

  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(50) COLLATE utf8_bin NOT NULL,
  `last_name` varchar(50) COLLATE utf8_bin NOT NULL,
  `email` varchar(100) COLLATE utf8_bin NOT NULL,
  `join` datetime NOT NULL,
  `access` datetime NOT NULL,
  `fb_id` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)

  `session_id` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
  `http_user_agent` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
  `session_data` blob NOT NULL,
  `session_expire` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`session_id`)

The tables are very much self explanatory. There is one extra table for sessions which I am using for storing them in the database. You are advised to follow this for an added layer of protection from web attacks.

Here is the PHP code which handles the AJAX requests (for adding and deleting comments from the database)


## Server's date and time. Converting it as per local time.
$date = date('Y-m-d H:i:s');
$con_date = date('c', strtotime($date));

if($sesslife == true) {
	if(isset($_GET['r'])) {
		## Execute functions as per the request
		$r = clean_input($_GET['r']);
			## For deleting photo from the database and removing thumbnails from the server
			if($r == 'post_comment') {
				if(isset($_GET['token']) && isset($_GET['msg'])) {
					$token = clean_input($_GET['token']);
					$msg = clean_input($_GET['msg']);
						if(!empty($token) && !empty($msg)) {
							if(isset($_SESSION['token']) && $token == $_SESSION['token']) {
									@@ We have done the CSRF validation and will now store the comments in the database and send the
									result back to the index.php page.
								try {
									$insert_comment = 'INSERT INTO `comments`(`comment`, `m_id`, `datetime`) VALUE(:comment, :userid, :datetime)';
									$insert_comment_do = $db->prepare($insert_comment);
									$insert_comment_do->bindParam(':comment', $msg, PDO::PARAM_STR);
									$insert_comment_do->bindParam(':userid', $userid, PDO::PARAM_INT);
									$insert_comment_do->bindParam(':datetime', $date, PDO::PARAM_STR);
									$comment_id = $db->lastInsertId();

									## Fetching the gravatar photo
									$gravatar = get_gravatar($username);

									<div class="comments clearfix" id="comment-<?php echo $comment_id; ?>">
										<div class="pull-left lh-fix">
											<img src="<?php echo $gravatar; ?>">

										<div class="comment-text pull-left">
											<span class="color strong"><a href="http://www.facebook.com/profile.php?id=<?php echo $facebook_id; ?>" target="_blank"><?php echo $first_name.' '.$last_name; ?></a></span> &nbsp;<?php echo $msg; ?>
											<span class="info"><abbr class="time" title="<?php echo $con_date; ?>"></abbr>
												&middot; <a href="javascript:;" id="delete-<?php echo $comment_id; ?>" class="delete color">Delete</a>

								} catch(PDOException $e) {
									## Sending the error back to the page to show sensible message to the user
									echo 'failed';

			if($r == 'delete_comment') {
				if(isset($_GET['token']) && isset($_GET['c_id'])) {
					$token = clean_input($_GET['token']);
					$comment_id = intval($_GET['c_id']);
						if(!empty($token) && !empty($comment_id)) {
							if(isset($_SESSION['token']) && $token == $_SESSION['token']) {
								try {
									$del_comment = 'DELETE FROM `comments` WHERE `id` = :comment_id AND `m_id` = :userid';
									$del_comment_do = $db->prepare($del_comment);
									$del_comment_do->bindParam(':comment_id', $comment_id, PDO::PARAM_INT);
									$del_comment_do->bindParam(':userid', $userid, PDO::PARAM_INT);

									## Sending the response back to the page
									echo 'success';
								} catch(PDOException $e) {
									## Place to catch and log errors.
									echo 'failed';

The step-by-step working of the code above.

  1. Checks whether the user is authenticated and is logged-in to the system
  2. Checks for the type of request made using the $_GET[“r”] global variable. The request can be either post_comment or delete_comment.
  3. Then verifies the token key and matches it with the one stored in sessions. If they both match, then the request is processed.
  4. Once the request is complete, the result is sent back to the page. In our case, index.php page.

Let’s move to the jQuery code now.

		@@ For deleting comments. Sends an AJAX call to ajax.php with request type - delete_comment
	$(document).on('click', '.delete', function() {
		var comment_id = $(this).attr('id').replace('delete-', '');
		var parent = $('#comment-'+comment_id);

			url: 'php/ajax.php',
			type: 'GET',
			data: 'r=delete_comment&token=<?php echo $token; ?>&c_id='+comment_id,
			success: function(data) {
				if(data == 'success') {

		@@ For adding comments. Sends an AJAX call to ajax.php with request type - post_comment
	$(msg).keypress(function(e) {
		if(e.which == 13) {
			var val = $(msg).val();

				url: 'php/ajax.php',
				type: 'GET',
				data: 'r=post_comment&token=<?php echo $token; ?>&msg='+escape(val),
				success: function(data) {
						if(data != 'failed') {

The above jQuery code is for both post_comment and delete_comment requests. For delete_comment request the following steps are executed.

  1. On click of the link with “.delete” class, we fetch the ID of the clicked link. This ID is nothing but the comment ID.
  2. After obtaining the comment ID, an AJAX request is sent to ajax.php with few required parameters.
  3. Then the comment is removed if the “success” response is received from the ajax page.

The post_comment request is completed in the following steps.

  1. On pressing the enter key in the comment box, an AJAX request is initiated. The only exception to this is if no comment text is entered.
  2. The post_comment request is sent to ajax.php with the required parameters.
  3. If the request is accepted and validated, the ajax page returns the result which is prepended to the “commentscontainer” DIV.
  4. If the result fails, no action is taken.

And that’s it. You have reached the end of this short and simple tutorial. Implementing this system is not easy but it’s not difficult either. Just follow the steps above, download the files & go through them and I am sure you will come out with a better system than this one.[/sociallocker]

The steps explained throughout this tutorial form the core of the comments system. I have tried to keep this system as simplified as I could. Please note that I have not explained you the process of Facebook authentication as I have already covered that over here. I hope that you guys going to like this effort of mine. Do let me know what you think of this in the comments.


  1. hi bro enhanced tutorial nice tutorial i downloaded the code but and hosted in localhost in wamp but when i try to execute the code it shows empty page please tell me how to execute that code thanks

    • Hey!

      Have you connected to the database correctly? Database details are stored in the database.php file located in php/common folder. Change the details with yours.

      Paste the SQL structure at the beginning of the post in your database to create the required tables for the demo to work.

  2. Hello I am trying to implement your demo but i got a ‘server error’ message after creating the database and navigating to the index.php

      • Okey thx, i suggest edit your code,because now incorrect,,because the “init.php” not exist on zip, and if you try this code,that’s becouse fail and you get php error.

          • Can you try downloading the zip file again because init.php is present in the zip. But as you are saying it’s missing from your download, please let me know your email so that I can mail you the file.

          • Can you help me a little bit please?

            I’d like to intagrate this for my wordpress,but this a little complicated.

            I’d like to create a link for meta datas(like poseted on,posted in,category,etc)the link name is quick comment.

            When you click this,you can get this comment form and you can add comment for the wordpress comment database.
            This important:
            If you’re not login,must be register with wordpress register form.
            And if possible,the comment form try get the avatar picture from gravatar.com.
            Thx for your help and your time!

          • Hey!

            I wish I could spare time to help you out in this but I am fully occupied these days. Still, I will try to post a topic on WordPress integration in coming weeks.

          • Thank you for your help and time!
            You’re the best!
            Please write me a comment if you’re done,tha’s becouse i get new mail for your comment.

  3. Now I intalled this for my server and I gess I found a bug.
    When you click the login link,the link redirect to facebook,then redirect to your site.
    How can I fix this?

  4. I am trying Enhanced comments system using PHP, mySQL, jQuery, and AJAX. I get the following error.
    Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App’s settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App’s domains.

  5. What are the chances, you can add comment replies, collapsible comments,
    A ‘Like’ system for the comments.. and use the profile picture from FB
    when you connect *you can save it to your server after you connect with
    FB* Then the only other thing I would need for this to be perfect. is to
    make it object oriented, I think? with a Simple API. So We web
    developers can implement it on different parts of our page. i.e. On each
    file someone can download. on each picture. On each profile. Just
    anywhere we need comments, it’d be nice to be able to add it to that

    i dunno maybe with a function: Comments($contentType, $contentID, $userID)

    something like that. what do you think?

    • Hi,

      Thank you for the suggestion. It’s a nice one. I look forward to further develop this comments system but as of now don’t have much time. It will be good to see any member joining hand to speed up things. :)

  6. Hello, I am trying to use this comment system, but I have got error after I pressed log in link for adding comment. I am redirected but with this error message:
    “Given URL is not allowed by the Application configuration.: One or more
    of the given URLs is not allowed by the App’s settings. It must match
    the Website URL or Canvas URL, or the domain must be a subdomain of one
    of the App’s domains.”

    Did you ever fall in such a situation ? Many thanks.

  7. Hi Akshit!

    I’m returning a blank page when i load init.php? I’ve connected to the database as the black screen does not appear. Any thoughts?


Leave a Comment.