Advertisement
PHP

Asynchronous Comments with PHP, jQuery, and JSON

by

In this article, we’re going to look at how we create a simple but effective means of capturing and displaying visitor comments using a blend of jQuery, PHP and JSON. In the public forum that is the blogosphere, the ability to capture and display visitor comments on your blogs can give you instant feedback and opinions from the people that matter most – those that read your blog.

Outline

We’ve several tasks that need to be accomplished in order to complete this example; when the page on which the comments are displayed is initially loaded, we need to display all of the existing comments. Additionally, when a new comment is made, we’ll need to display this on the page after the existing comments, as well as sending the new comment to the server for storage with the existing comments.

Tools Required

We’ll be using jQuery (version 1.3.1), obviously, because it rocks, and we’ll be using JSON because it’s a light-weight and efficient format for transporting data across networks. We’ll also be using a little simple PHP to interact with a MySQL database. You’ll need to have access to an installation of MySQL server and should prepare a new database called comments that contains a table, also called comments, which has a name column and a comment column. Running a select all query to your database should produce a result similar to that shown below:

demonstration

Getting Started – The Stored Comments

Let’s make a start by creating the PHP file that reads the comments from the database and returns them to the page; this way, when we come to code the page, the data will already be available for us to use. In a new file in your text editor add the following code:

<?php

  //db connection detils
  $host = "localhost";
  $user = "root";
  $password = "your_password_here";
  $database = "comments";
	
  //make connection
  $server = mysql_connect($host, $user, $password);
  $connection = mysql_select_db($database, $server);
	
  //query the database
  $query = mysql_query("SELECT * FROM comments");
	
    //loop through and return results
  for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
    $row = mysql_fetch_assoc($query);
    
    $comments[$x] = array("name" => $row["name"], "comment" => $row["comment"]);		
  }
	
  //echo JSON to page
  $response = $_GET["jsoncallback"] . "(" . json_encode($comments) . ")";
  echo $response;  

?>

Save this as comments.php. Let’s briefly walk through what we do with this code. We store the access credentials for our server in the first four variables and following this, we connect to the database. We then query the database and select all of the data from it.

For Loop

In the next section of code we use a for loop to cycle through each row of data. On each iteration of the loop we add a new item to an array ($comments). The array is a multidimensional associate array and each item will have two sub items which are given the keys name and comment, matching the columns in our table. The value of each item will be the data from each respective field in the current row.

JSON Encode

Finally we package up the completed JSON object in a GET request and then use the native PHP json_encode function to convert our array into a properly formatted JSON object. We’ll be using a JSONP callback in the JavaScript, which is why we need to use a get response and also why we wrap the JSON encoded array in brackets. To clarify the structure of the data that we’re returning, if we were writing it out manually we would do something like this:

([
  {name:"a name", comment:"a comment"},
  {name:"a name", comment:"a comment"},
  { etc }
])

This consists of a simple array, where each item in the array is an object. These inner objects each have two properties – author and comment, where the values of these properties are the data extracted from the text file. Nesting the inner objects in an array makes it extremely easy for us process the data with jQuery. The following screenshot shows how the JSON object will be interpreted by Firebug:

demonstration

Displaying the Stored Comments

Now that we have an object to work with, we can create the HTML page that will display the comments. In a new file in your text editor add the following mark-up:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="comments.css">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Asynchronous Comments</title>
  </head>
  <body>
    <div id="content">
      <h2>Some Content</h2>
      <p>Lorem ipsum dolor...</p>
    </div>
    <div id="comments">
      <h2>Reader Comments</h2>
    </div>
    <div id="leaveComment">
      <h2>Leave a Comment</h2>
      <div class="row"><label>Your Name:</label><input type="text"></div>
      <div class="row"><label>Comment:</label><textarea cols="10" rows="5"></textarea></div>
      <button id="add">Add</button>
    </div>
    <script type="text/javascript" src="jquery-1.3.1.min.js"></script>
  </body>
</html>

Save this file as comments.html. Most of the mark-up is non-essential and is used to give the example some substance. On the page we have some dummy content, a container which the existing comments can be rendered into and some basic form elements used to leave a new comment. In the head of the page we link to a stylesheet and at the end of the body we link to the jQuery library.

CSS

The stylesheet used in this example is non-essential and is used simply to present the example neatly. It consists of the following CSS:

body { font-family:verdana; font-size:11px; color:#ffffff; }
#content {
  width:400px; height:195px; border:3px solid #000000; margin:0 auto 10px;
  font-size:13px; background-color:#575454;
}
#content p { padding:0 10px; }
#comments {
  width:400px; border:3px solid #000000; margin:0 auto 10px;
  padding-top:5px; background-color:#575454;
}
.comment {
  background-color:#d4d7d6; border:1px solid #000000;
  padding:5px 0 5px 5px; color:#000000;
}
#leaveComment {
  width:400px; border:3px solid #000000; margin:0 auto;
  overflow:hidden; position:relative; background-color:#575454;
}
h2 { text-align:center; margin:5px 0 10px; }
.row { padding-left:5px; margin-bottom:5px; clear:both; overflow:hidden; }
.row label {
  width:100px; text-align:right; margin-right:5px; display:block;
  float:left; font-weight:bold; padding-top:5px;
}
.row input, .row textarea, .row div {
  width:280px; display:block; float:left;
}
#add {
  position:absolute; bottom:5px; left:60px; font-weight:bold;
  font-size:10px;
}

Save this as comments.css in the same directory as the HTML page. I won’t cover exactly what this code does as it’s pretty trivial and is used purely for display purposes. It should cause the page to be displayed as follows:

demonstration

Javascript

Now we can add the JavaScript that will request the JSON object from the server, process it and display the comments. Directly after the link to jQuery add the following script block:

<script type="text/javascript">
  $(function() {
			
    //retrieve comments to display on page
    $.getJSON("comments.php?jsoncallback=?", function(data) {
				
      //loop through all items in the JSON array
      for (var x = 0; x < data.length; x++) {
					
        //create a container for each comment
        var div = $("<div>").addClass("row").appendTo("#comments");
						
        //add author name and comment to container			    
        $("<label>").text(data[x].name).appendTo(div);		   
        $("<div>").addClass("comment").text(data[x].comment).appendTo(div);
      }
    });			
  });			
</script>

Again this code is fairly trivial; when the page has loaded, we use the getJSON method to request the JSON object from the PHP file, specifying the path to the file as the first argument. We add the JSONP callback - ?jsoncallback=? - to the end of the URL and then specify an anonymous callback function as the second argument, which will be executed if and when the request returns successfully.

Within our callback we have a simple for loop which is used to loop through each item in the JSON array. For each item we create a container div which is given a class of row and is then appended to the main comments container div.

We then specify a label and set the text of the label to the value of the name property of the object in the current array item. After the label has been appended to the current container div, we create another div which is used to hold the value of the comment property. The comment is then appended to the current container div.

Now when we run the page, we should find that the comments from the database are displayed within the specified container div:

demonstration

Adding New Comments Asynchronously

For the final part of this tutorial we can see how easy it is to automatically insert a new comment after the existing comments, while at the same time sending the new comment to the server to be added to the database so that it can be displayed automatically when the page is next loaded. Add the following new code directly after the getJSON method:

//add click handler for button
$("#add").click(function() {
				
  //define ajax config object
  var ajaxOpts = {
    type: "post",
    url: "addComment.php",
    data: "&author=" + $("#leaveComment").find("input").val() + "&comment=" + $("#leaveComment").find("textarea").val(),
    success: function(data) {
							
      //create a container for the new comment
      var div = $("<div>").addClass("row").appendTo("#comments");
						
      //add author name and comment to container
      $("<label>").text($("#leaveComment").find("input").val()).appendTo(div);
      $("<div>").addClass("comment").text($("#leaveComment").find("textarea").val()).appendTo(div);
    }
  };
					
  $.ajax(ajaxOpts);
});

Again, this is very straight-forward code – what we’re doing is quite complex, but jQuery abstracts away all the difficulty and cross-browser trickiness, leaving us to write just a few lines of code. We first set a click handler for the add comment button. This will execute the anonymous function specified as an argument to the click method whenever the button is clicked.

Within this function we first create a new literal object which is used to configure the new AJAX request. We specify the type of request, the URL of the resource we’re requesting, some data and a success callback function. Within our success function all we do is get the contents of the input and textarea and add them to the comments div in the same way that we did with the original comment data received when the page loads.

Database Connection

We’ll need one more PHP file in order to write the new comment to the database:

<?php

  //db connection detils
  $host = "localhost";
  $user = "root";
  $password = "your_password_here";
  $database = "comments";
	
  //make connection
  $server = mysql_connect($host, $user, $password);
  $connection = mysql_select_db($database, $server);
	
  //get POST data
  $name = mysql_real_escape_string($_POST["author"]);
  $comment = mysql_real_escape_string($_POST["comment"]);

  //add new comment to database
  mysql_query("INSERT INTO comments VALUES(' $name ',' $comment ')");

?>

Save this file as addComment.php. We specify our connection information once more and connect to the database. We then get the data sent by our JavaScript from the $_POST superglobal variables and then use the mysql_query function to insert the new data into the table. Notice that we use the mysql_real_escape_string function to prevent any misuse of our database; although it’s unlikely that any harm could come from an attacker gaining access to this particular database, it’s always wise to sanitize any data before it is added.

Now we should find that when we add a comment, the new comment is displayed on the page, and subsequent reloads of the page will show the new comment:

demonstration

Summary

Asynchronous comments are made easy with a combination of jQuery, simple scripts and the lightweight and highly effective JSON format. Although this is just a basic example, to which we could do so much more, I think you’ll agree when I say that it’s easy to implement a basic, but robust solution to the capture and display of comments from your visitors.

To learn more from Dan Wellman, be sure to sign up for our Net Plus program, where you can read, among others, his in depth tutorial/screencast "Build an Advanced "Poll" jQuery Plugin". Sign up now!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Related Posts
  • Code
    JavaScript & AJAX
    Connect 4 With Socket.ioSocket io wide retina preview
    Today we'll see how we can use Node.js and Socket.io to create a multiplayer Connect 4 style game.Read More…
  • Code
    Theme Development
    Custom Controls in the Theme CustomizerTheme customizer custom control 400
    In the last article, we explored the advanced controls available in the Theme Customizer, and how to implement them. We’re going to look at how to create our own custom control, allowing you to choose which Category of Posts are displayed on the home page. To get started, download version 0.6.0 of our Theme Customizer Example.Read More…
  • Web Design
    UX
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…
  • Code
    PHP
    25 Laravel Tips and TricksCode
    There was a period of time, not too long ago, when PHP and its community were, for lack of better words, hated. Seemingly, the headline joke of every day was one that related to how terrible PHP was. Let's see, what new PHP-slamming blog article will be posted today?Read More…
  • Code
    JavaScript & AJAX
    Working With IndexedDB - Part 2Indexeddb retina preview
    Welcome to the second part of my IndexedDB article. I strongly recommend reading the first article in this series, as I'll be assuming you are familiar with all the concepts covered so far. In this article, we're going to wrap up the CRUD aspects we didn't finish before (specifically updating and deleting content), and then demonstrate a real world application that we will use to demonstrate other concepts in the final article.Read More…