Simple commenting system using AJAX. Comments in HTML, CSS, PHP Comments from Facebook: pros and cons

This time we are making a simple AJAX commenting system. This will demonstrate how to achieve efficient interoperability between JQuery and PHP/MySQL using JSON. The system works in such a way that added comments are placed on the page without completely reloading it, giving the feeling of the site running only on the user's computer, thereby avoiding the need to wait for some time to reload the page with the added comment.

Here's a rough demo of what we plan to implement:

Step 1 - XHTML

First, let's take a look at the comment markup. This code is generated by PHP in a comment, which we're going to look at in a moment.

Demo.php

Name
July 30, 2010

A comment

The Div of the avatar class contains a hyperlink corresponding to the avatar (if the user specified a valid link to the avatar when sending a comment), for example from gravatar.com. Well, we'll come back to this when we work with PHP. Finally, we have the name and time also in the DIVs, as well as the comment, that is, the text itself in the paragraph.

Another important element in the XHTML part is the comment submission form itself (all fields except URL fields are required to be filled out).

Demo.php

Add a comment

Step 2 - PHP

PHP handles connections to the MySQL database and creates comment markup. In addition, AJAX is used at the end and inserts a comment into the comments table. You can see the code that displays comments on the page below.

Demo.php /* / Select all comments and fill the $comments array */ $comments = array(); $result = mysql_query("SELECT * FROM comments ORDER BY id ASC"); while($row = mysql_fetch_assoc($result)) ( $comments = new Comment($row); )

The MySQL query fetches all entries from the database and populates the $comments array with the comment class object you see below. This array is output after the script is executed.

Demo.php /* / Display comments one by one */ foreach($comments as $c)( echo $c->markup(); )

Each comment has a markup() method, which generates HTML code for printing the page. You can see this method and class below.

The class takes a string from the database (fetched with mysql_fetch_assoc()) and stores it in the $data variable. It is only available to methods of this class and cannot be accessed from outside.

Comment.class.php – Step 1 class Comment ( private $data = array(); public function __construct($row) ( /* / Constructor */ $this->data = $row; ) public function markup() ( / */ This method outputs the XHTML markup comment */ // Create an alias so we don't have to write // $this->data data every time: $d = &$this->data; $link_open = ""; $link_close = ""; if($d["url"])( // If the person filled in the URL when // adding a comment// Define the hyperlink $link_open = ""; $link_close = ""; ) // Time conversion $d["dt"] = strtotime($d["dt"]); // Required for default Gravatar images: $url = "http://".dirname($_SERVER["SERVER_NAME"]. $_SERVER["REQUEST_URI"])."/img/default_avatar.gif"; return "

".$link_open." ".$link_close."
".$link_open.$d["name"].$link_close."

".$d["body"]."

"; }

This script uses Gravatar to show avatars in comments. For those who haven't used Gravatar, it is a very useful service that allows you to associate an avatar with your email address. The avatar can be easily taken by passing the hash via md5().

Notice on line 39 above it - the script tries to figure out the URL it is on and determines the exact address of the default_avatar.gif image. This GIF is transmitted to Gravatar using an md5 hash, so if an avatar was found on this email address, a fallback stock image is displayed instead.

Comment.class.php – Step 2 public static function validate(&$arr) ( /* / This method used to validate data/passed via AJAX. // This returns true/false depending on / whether the data is valid, and the $arr array is passed as paremter / (note the ampersand above) / Either valid data entry, or error messages. */ $errors = array(); $data = array(); // Use the filter_input function introduced in PHP 5.2.0 if(!($data["email"] = filter_input(INPUT_POST,"email",FILTER_VALIDATE_EMAIL))) ( $errors["email"] = "Please enter a valid Email."; ) if(!($data["url"] = filter_input(INPUT_POST,"url",FILTER_VALIDATE_URL))) ( // If the URL field does not match the wrong URL $url = ""; ) // Usage filters with a custom // callback function: if(!($data["body"] = filter_input(INPUT_POST,"body",FILTER_CALLBACK, array("options"=>"Comment::validate_text")))) ( $ errors["body"] = "Comment error."; ) if(!($data["name"] = filter_input(INPUT_POST,"name",FILTER_CALLBACK, array("options"=>"Comment::validate_text") ))) ( $errors["name"] = "Name error."; ) if(!empty($errors))( //If there are errors, write $errors to the $arr array: $arr = $errors; return false; ) foreach($data as $k=>$v)( $arr[$k] = mysql_real_escape_string($v); ) // Make sure the letters are in lowercase // (for the correct Gravatar hash): $arr ["email"] = strtolower(trim($arr["email"])); return true; )

validate() is defined as static in the manner described above. This means that it can be called as Comment::validate() directly, without having to create an object of that class. This method does not validate input that is provided via AJAX.

This method uses the new filter functions that are available in PHP 5.2.0. This allows us to easily validate and filter any input that is passed into the script. For example filter_input(INPUT_POST, "URL", FILTER_VALIDATE_URL) means that we are checking $_POST["url"] is a valid URL. If so, then the function returns the value of the variable, otherwise the returns are false.

This is very useful, since until now, we had to use our own regular expressions to check data. Additionally, another advantage is that this data is taken before any configuration-specific transformations (such as magic quotes).

We also have the ability to specify a custom function that is going to apply some more advanced modifications to the data, as seen in lines 31 and 37.

Comment.class.php – Step 3 private static function validate_text($str) ( /* / This method is used internally as FILTER_CALLBACK */ if(mb_strlen($str,"utf8") , ", etc..) and convert // Newlines to
tags: $str = nl2br(htmlspecialchars($str)); // Remove any remaining newlines $str = str_replace(array(chr(10),chr(13)),"",$str); return $str; )

The last method is validate_text, which we pass as a callback function. It escapes all HTML special characters, effectively eliminating XSS attacks from them. It also replaces character strings with
lines.

Submit.php /* / This array will be filled with either / The data that was submitted to the script or / Error messages: /*/ $arr = array(); $validates = Comment::validate($arr); if($validates) ( /* Everything is good, insert it into the database: */ mysql_query(" INSERT INTO comments(name,url,email,body) VALUES ("".$arr["name"]."", " ".$arr["url"].", "".$arr["email"].", "".$arr["body"]."")"); $arr["dt" ] = date("r",time()); $arr["id"] = mysql_insert_id(); /* / Data in $arr insert query, / but unescaped text, / so we use stripslashes / for all array elements: /*/ $arr = array_map("stripslashes",$arr); $insertedComment = new Comment($arr); /* Output markup */ echo json_encode(array("status"=>1, "html" =>$insertedComment->markup())); ) else ( /* Display error messages */ echo "("status":0,"errors":". json_encode($arr).")"; )

submit.php receives the comment data as an AJAX request. It checks it and produces a JSON object, either the XHTML markup that was successfully rendered, or a list of error messages. JQuery uses ownership status to determine whether error messages should be displayed or a page markup comment should be added.

You can see two examples below.

Hello, friends and blog guests! Today I’ll tell you using PHP and MySQL. And we will also talk about commenting systems for the site and we will choose the best one for your site from the ones I offer.

Question one: by using PHP and MySQL?

To do this, you and I first need to create a table in the database of your site, which will be called - comments. This created table will store comments in fields with the following designations:

id is a unique identifier.
page_id— this field will store the identifier of the site page on which this comment is located.
name- this is the name of the commentator who left this comment.
text_comment— accordingly, this is the text of the current comment.

The next step, after creating a table for comments in the database, we need to implement special code for our future comments on the site. This code on the site will allow our commentators to add their comments to our articles. Here is the code:


It's simple HTML form comments for the site. You place it on your website in a place where it is convenient for leaving a comment on a post - naturally, under the post itself.

query("INSERT INTO `comments` (`name`, `page_id`, `text_comment`) VALUES ("$name", "$page_id", "$text_comment")");// Add a comment to the table header(" Location: ".$_SERVER["HTTP_REFERER"]);// Do we redirect back?>

The last step in creating a comment form for a site in PHP and MySQL is to display our comments on the site page. Here's the code for this:

query("SELECT * FROM `comments` WHERE `page_id`="$page_id""); //Fetch all comments for this page while ($row = $result_set->fetch_assoc()) ( print_r($row); //Output comments echo "
"; } ?>

That's all! Our simple form comments for the site have been created and can work on the site.

But this is certainly not for a beginner who will not bother with all this HTML, PHP and MySQL code. Nor will he learn how to create a database. He needs everything at once, quickly and without headaches. I'm right? Of course you're right!

Then let's move on to the next section of my material and find out everything about ready-made comment systems for the site and choose the most convenient, functional and acceptable for your site...

Comment systems for the site. Which one to choose?

How to make comments on the site- this is an important question because comments on a site play an important role not only for communication between the site owner and the visitor, but comments are also important for SEO promotion and promotion.

With the help of comments on the site, the site’s position in search results increases and improves behavioral factors, traffic to the site increases, and consequently your earnings increase. You see how important comments are for the site!

So let's take a look how to make comments on the site and which one commenting system choose the best option?

In general, comments on websites are displayed in many ways. These are special plugins for wordpress engines and comments from social networks all sorts of things, such as In contact with, Facebook, Disqus. There are also independent services that offer their own comment systems for the site, for example.

I’ll now give you one tablet that will immediately put everything in its place and no questions will arise about choosing a comment system for the site:

Here you can clearly and clearly see which comment system is the best and several presented ones, which are most often used by webmasters on their resources. I think that explanations are unnecessary here and the choice is yours!

Step 1 - XHTML

First, let's look at the comment markup. This code generated by PHP with class Comment .

demo.php

Username
30 Jun 2010

Comment text

div avatar contains a link (if the user entered the correct URL when posting a comment) and an avatar image, which we get from gravatar.com. We'll return to generating the markup in the PHP step. Finally follow div name div time and comment text.

Another important element in XHTML is the comment form. She is sent with POST. All fields except URL must be completed.

demo.php

Add a comment

The form is submitted using AJAX. The check is performed in background V submit.php. Each field has a corresponding element label, with the attribute set for .

Step 2 - PHP

PHP handles the communication with the MySQL database and generates the comment markup. It also receives the end of the AJAX request and inserts the comment data into the table comments.

demo.php

/* / Select all comments and fill the $comments array with objects */ $comments = array(); $result = mysql_query("SELECT * FROM comments ORDER BY id ASC"); while($row = mysql_fetch_assoc($result)) ( $comments = new Comment($row); )

MySQL query selects all records from table and fills array $comments class objects comment. This array is output further when the script is executed.

demo.php

/* / Print comments one by one: */ foreach($comments as $c)( echo $c->markup(); )

Each comment has a method markup(), which generates the correct HTML code, ready to be displayed on the page. Below are the class and method definitions.

The class gets a row from the database (obtained using mysql_fetch_assoc()) and stores it in a variable $data. It is available only to the class method.

comment.class.php - Part 1

class Comment ( private $data = array(); public function __construct($row) ( /* / Constructor */ $this->data = $row; ) public function markup() ( /* / This method outputs XHTML markup for comments */ // Set an alias so as not to write $this->data every time: $d = &$this->data; $link_open = ""; $link_close = ""; if($d["url"] )( // If a URL was entered when adding a comment, // determine the opening and closing tags of the link $link_open = " "; $link_close = ""; ) // Convert the time to UNIX format: $d["dt"] = strtotime($d["dt"]); // Needed to set the default image: $url = "http://".dirname ($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"])."/img/default_avatar.gif"; return "
".$link_open." ".$link_close."
".$link_open.$d["name"].$link_close."
".date("d M Y",$d["dt"])."

".$d["body"]."

"; }

The script uses gravatar to represent the avatar in comments. Gravatar is a very useful service that matches an avatar with an email address. The avatar image can be easily obtained by passing the encoded function md5() your email address on gravatar.com.

The script determines the URL where it is executed and determines the exact address of the image default_avatar.gif. This image is transmitted in parallel with the md5 hash, and if no avatar was found for the transmitted email address, an alternative image will be displayed.

comment.class.php - Part 2

public static function validate(&$arr) ( /* / This method is used to validate data sent via AJAX. / / It returns true/false depending on the correctness of the data, and fills / the $arr array, which is passed as a parameter with either data or error message. */ $errors = array(); $data = array(); // Use the filter_input function introduced in PHP 5.2.0 if(!($data["email"] = filter_input(INPUT_POST,"email ",FILTER_VALIDATE_EMAIL))) ( $errors["email"] = "Please enter a valid Email."; ) if(!($data["url"] = filter_input(INPUT_POST,"url",FILTER_VALIDATE_URL))) ( // If an incorrect URL was entered in the URL field, // act as if the URL was not entered: $url = ""; ) // Use a filter with a callback function: if(!($data["body"] = filter_input(INPUT_POST,"body",FILTER_CALLBACK,array("options"=>"Comment::validate_text")))) ( $errors["body"] = "Please enter the comment text."; ) if(!( $data["name"] = filter_input(INPUT_POST,"name",FILTER_CALLBACK,array("options"=>"Comment::validate_text")))) ( $errors["name"] = "Please enter a name. "; ) if(!empty($errors))( // If there are errors, copy the $errors array to $arr: $arr = $errors; return false; ) // If the data is entered correctly, clear the data and copy it to $arr : foreach($data as $k=>$v)( $arr[$k] = mysql_real_escape_string($v); ) // email must be in lowercase: $arr["email"] = strtolower(trim($ arr["email"])); return true; )

Method validate()(also part of a class) defined as static. This means that it can be called directly using the construct Comment::validate(), without creating a class object. This method checks the data that is sent via AJAX.

The method uses new feature filter, which became available in PHP 5.2.0. This way we can easily check and filter the data that is passed to the script. For example, filter_input(INPUT_POST,’url’,FILTER_VALIDATE_URL) means we are checking whether $_POST["url"] correct URL address. If so, then the function returns the value of the variable, otherwise it returns the value false.

Before using such a function, it was necessary to use regular expressions to validate data (using a series of constructs if). An additional advantage is that we receive the data before any specific transformations are carried out.

It is also possible to specify a function that will carry out additional data modifications.

comment.class.php - Part 3

private static function validate_text($str) ( /* / This method is used as FILTER_CALLBACK */ if(mb_strlen($str,"utf8")<1) return false; // Кодируем все специальные символы html (<, >, ", & .. etc) and convert // the newline character into a tag
: $str = nl2br(htmlspecialchars($str)); // Remove any remaining newlines $str = str_replace(array(chr(10),chr(13)),"",$str); return $str; )

Last method validate_text passed as a return function in two calls filter_input. It converts all HTML special characters, which effectively blocks XSS attacks. Also it replaces newlines with tags
.

submit.php

/* / This array will be filled with either data / that is passed to the script, / or error messages. /*/ $arr = array(); $validates = Comment::validate($arr); if($validates) ( /* Everything is fine, insert the data into the database: */ mysql_query(" INSERT INTO comments(name,url,email,body) VALUES ("".$arr["name"]."", "".$arr["url"].", "".$arr["email"].", "".$arr["body"]."")"); $arr["dt "] = date("r",time()); $arr["id"] = mysql_insert_id(); /* / The data in $arr is prepared for the mysql query, / but we need to output to the screen, so / prepare all elements in the array: /*/ $arr = array_map("stripslashes",$arr); $insertedComment = new Comment($arr); /* Output the markup of the newly inserted comment: */ echo json_encode(array("status "=>1,"html"=>$insertedComment->markup())); ) else ( /* Display error messages */ echo "("status":0,"errors":".json_encode($arr )")"; )

submit.php gets a comment from the data via an AJAX request. Validates it and outputs a JSON object containing either XHTML markup with a comment inserted, or a list of errors. jQuery uses the property status to determine what needs to be output - either an error message or adding comment markup to the page.

Below are two examples.

Successful response

( "status": 1, "html": "Html Code Of The Comment Comes Here..." )

Property html contains comment code.

Error response

( "status": 0, "errors": ( "email": "Please enter a valid Email.", "body": "Please enter a comment body.", "name": "Please enter a name." ) )

If there is an error, jQuery loops through the errors object and displays messages next to the fields that have errors.

Step 3 - CSS

Now that the markup is correctly generated and displayed on the page, we can move on to setting styles.

styles.css - Part 1

.comment, #addCommentContainer( /* Style for comments */ padding:12px; width:400px; position:relative; background-color:#fcfcfc; border:1px solid white; color:#888; margin-bottom:25px; / * CSS3 rounded corners and shadows */ -moz-border-radius:10px; -webkit-border-radius:10px; border-radius:10px; -moz-box-shadow:2px 2px 0 #c2c2c2; -webkit-box- shadow:2px 2px 0 #c2c2c2; box-shadow:2px 2px 0 #c2c2c2; ) .comment .avatar( /* / The avatar is positioned absolutely. / Outer offset for the comment div /*/ height:50px; left:-70px; position :absolute; width:50px; background:url("img/default_avatar.gif") no-repeat #fcfcfc; /* Center vertically: */ margin-top:-25px; top:50%; -moz-box-shadow :1px 1px 0 #c2c2c2; -webkit-box-shadow:1px 1px 0 #c2c2c2; box-shadow:1px 1px 0 #c2c2c2; )

div .comment And #addCommentContainer have the same style. Uses several CSS3 rules for rounding corners and reflecting shadows.

styles.css - Part 2

.comment .avatar img( display:block; ) .comment .name( font-size:20px; padding-bottom:10px; color:#ccc; ) .comment .date( font-size:10px; padding:6px 0; position:absolute; right:15px; top:10px; color:#bbb; ) .comment p, #addCommentContainer p( font-size:18px; line-height:1.5; overflow-x:hidden; ) #addCommentContainer input, # addCommentContainer textarea( /* Input style */ display:block; border:1px solid #ccc; margin:5px 0 5px; padding:3px; font-size:12px; color:#555; font-family:Arial, Helvetica, sans-serif; ) #addCommentContainer textarea( width:300px; ) label( font-size:10px; ) label span.error( color:red; position:relative; right:-10px; ) #submit( /* Submit button " */ background-color:#58B9EB; border:1px solid #40A2D4; color:#FFFFFF; cursor:pointer; font-family:"Myriad Pro",Arial,Helvetica,sans-serif; font-size:14px; font -weight:bold; padding:4px; margin-top:5px; -moz-border-radius:4px; -webkit-border-radius:4px; border-radius:4px; ) #submit:hover( background-color:# 80cdf5; border-color:#52b1e2; )

In the second part we set styles for comments and form elements. Note the selector input which highlights elements based on attribute type.

Step 4 - jQuery

Now let's move on to jQuery.

script.js

$(document).ready(function())( /* The following code is executed only after the DOM is loaded */ /* This flag prevents multiple comments from being sent: */ var working = false; /* Catch the form submission event: */ $(" #addCommentForm").submit(function(e)( e.preventDefault(); if(working) return false; working = true; $("#submit").val("Working.."); $("span .error").remove(); /* Send form fields to submit.php: */ $.post("submit.php",$(this).serialize(),function(msg)( working = false; $ ("#submit").val("Submit"); if(msg.status)( /* / If the insertion was successful, add a comment / below the last one on the page with the slideDown effect /*/ $(msg.html).hide ().insertBefore("#addCommentContainer").slideDown(); $("#body").val(""); ) else ( /* / If there are errors, loop through the / msg.errors object and display them to page /*/ $.each(msg.errors,function(k,v)( $("label").append(" "+v+""); )); ) ),"json"); )); ));

We use a function call $(document).ready(), which binds a function to an event. Variable working acts as a flag that signals that an AJAX request is in progress (thus preventing duplicates of the same comment).

In the return function for the AJAX POST request we check the property status to determine whether the comment was successfully inserted. If yes, we add the resulting markup to the page after the last comment with animation slideDown.

If there were problems, we display error messages by adding span error to the corresponding element label(element attribute label contains id input that has an error).

Ready!

Conclusion

To run the script on your server you need to create a table comments in your MySQL database. You can do this using SQL code from a file table.sql, which must be entered on the SQL tab in phpMyAdmin. Then you need to set the connection parameters to the MySQL database in the file connect.php .

Nowadays, many popular sites are not only a source of information, but also a place where this information can be discussed with other users; sites often turn into centers around which a community is formed.

Comments help build community

Now users come to you not just to read some news or article, but also to discuss it.

What is typical is that the reader could have found out the news itself in another place, but it is the community of interesting people, the opportunity to speak out and hear their opinions - that is what will lead to the fact that he will visit your site and go to the page with the news that he already knows.

Just ten years ago, the centers around which all life was in full swing were forums. However, nowadays this is no longer so convenient and popular; now most popular sites operate in blog format, and user communication occurs in comments.

Thus, comments are the factor that distinguishes ordinary sites from sites that are truly successful in their field. This applies to news sites, blogs, communities of interest, sometimes even online stores and various specialized sites.

Comments provide feedback and motivation

It is also important to remember that comments are a source of feedback from readers, which allows you to find out what exactly they like and what readers react to. And the better and more interesting your site is for visitors, the more often they return to you and recommend it.

In addition, feedback is always a good motivation for the authors and administrators themselves, which almost instantly allows you to feel that people are interested in what you do and your site. You can’t achieve this with a simple visitor counter.

What do we need from a commenting system?

So what should be the “correct” comments on a modern website?

  • Simple and understandable for readers.
  • Convenient and functional for administrators.

What options does a webmaster currently have?

Social Network Widgets

There is only one plus - there is a fairly high probability that the user is already logged in to the social network and therefore will not have to register.

Lots of cons

Russian-language services

Russian-language analogues are often completely paid and cannot boast of an attractive design.

SV Kament

The only exception here is the SV Kament system (svkament.ru), which is completely free and brings together the functionality of various Western commenting systems, but at the same time is focused on the Russian-speaking segment.

Let's take a quick look at what we'd like to see in our commenting system.

Tree comments with the ability to collapse individual discussion threads. They are very helpful in navigating the discussion when there are a lot of comments.

Social login- significantly simplifies registration and, as a result, increases the number of comments. Western studies show that using a social login sometimes increases conversion by more than 60%.

Rating comments- firstly, it helps highlight the most interesting and worthwhile comments, which is extremely convenient for readers, and secondly, it encourages users to write interesting messages.

Real time operation- the more convenient and faster the system works, the more people use it and the more often they write comments.

Notifications by email- how often we lose potential comments just because the user doesn't know that someone replied to his previous message.

From a management perspective

  • Management directly on the site.

  • User information.

  • A single comment control panel for the entire site.
  • Ability to appoint moderators.
  • Easy to install.

The SV Kament system also has a number of interesting features.

  • Social broadcasts- allow you to “return” communication to your website from social networks. If you have a VKontakte group in which you post announcements of new articles on the site, then often part of the discussion of the articles remains in the comments on the post itself, and it would be great to broadcast these comments back to your site.

  • User rating and status- allows you to highlight the most active and popular visitors, thus stimulating your users to visit more often, communicate more and write messages interesting to other people.

All at once?

There is a fairly common practice to place several commenting systems at once, for example, a separate VKontakte widget, a separate Facebook one, and a separate one for everyone else.

In my opinion, this is one of the worst decisions, but it is important to understand exactly what goals are being pursued.

If you just need to collect user reviews, then this method has a right to life, although a simple guest book or even an email address may be enough for this.

If our goal is to create a community and stimulate communication between users, then this approach is extremely harmful, because by dividing comments, we divide the communication itself, so instead of a single dialogue, we get a bunch of unrelated messages.

What kind of comments do you use? Do you consider comments important to your site, and how convenient and effective do you find comments on your site?