PHP - Simple Comments Script

In this article, I'll explain how to allow your users to post and view comments on your website without using any third party scripts. I'll explain how to develop a simple Comments class that you can reuse in other projects.

Background

When developing websites for my clients, I'm usually asked to add a simple comments form, where users can post and view comments. In these situations, I'm tempted to use third party commenting system such as Disqus, but often the clients want their own integrated solution. For this reason, I've developed a simple comments class that can be reused in other projects and in this tutorial I'll be showing you how to create your own.

Implementation

The chosen programming language for this tutorial is PHP and we'll be using MySql as our database. The first thing we need to do is create a database table that can store the comments. Listing 1.1 below shows a create table script. 

Listing 1.1

  1. CREATE TABLE comments (
  2. id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. uid VARCHAR(45) DEFAULT NULL,
  4. full_name VARCHAR(45) DEFAULT NULL,
  5. comment text,
  6. created_date_time datetime DEFAULT NULL,
  7. PRIMARY KEY (id)
  8. ) ENGINE=MyISAM
Notice that there is a field called uid, this field will store a unique id for a group of comments. For example, you may have multiples pages that need comments like an article website where each article has its own comments. Using this uid, we can query the database to only get comments for a particular page.

Now that the database table has been created, it's time to start some coding. We are going to create a simple PHP class, that we can use to add, query and delete comments. I'm going to be using PHP's PDO class, if your not familiar with PDO, I recommend, visiting the PHP PDO documentation before you continue here.

The Code

Open your editor of choice and create a new PHP file. The first thing, we're going to do is create a class called CommentManager. This class will allow us to add,get,delete comments. It will also initiate a database connection. Let's start with the initialization of the database connection. Copy the code from listing 1.2 below.

Listing 1.2

  1. class CommentManager {
  2.     private $pdo = null;
  3.     public function __construct($host, $dbname, $username, $password){
  4.         $this->pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
  5.         $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  6.     }
  7. }
The code above will attempt to create a new database connection using the PDO class when we instaniate a new CommentManager class. The class constructor will accept the database connection details making it reusable for other projects. Notice that I've set the ATTR_ERRMODE attribute. This is because PDO will only throw an exception if it fails to connect to a database. If you have any errors in your Sql queries, you wont get any error feedback. For this reason we need to set the ATTR_ERRMODE so errors will be thrown, in this case as an exception.

Now we need a method to add a comment. Copy the code in listing 1.3 below into your CommentManager class.

Listing 1.3

  1. public function addComment($fullName, $comment, $uid = null){
  2.     if ($this->pdo){
  3.         $stm = $this->pdo->prepare("INSERT INTO comments (full_name,comment,uid,created_date_time) VALUES (:full_name,:comment,:uid,NOW())");
  4.         $stm->bindParam(':full_name', $fullName);
  5.         $stm->bindParam(':comment', $comment);
  6.         $stm->bindParam(':uid', $uid);
  7.         if ($stm->rowCount()){
  8.             return true;
  9.         }
  10.     }
  11.     return false;
  12. }
The addComment method accepts 3 parameters with the third being optional. The uid is optional in case you only have a single page to provide comments for. The method checks if there is a PDO instance and prepares a simple insert statement. The bindParam() method is used to bind a parameter to a variable. It also properly deals with quotes. Finally the method will return a Boolean value indicating if the insert was a success.

Now that we can add a comment, we need a way to return all comments. Copy the code in listing 1.4 below into your class.

Listing 1.4

  1. public function getComments($uid=null){
  2.     if ($this->pdo){
  3.         $sql = 'SELECT * FROM comments ';
  4.         if($uid){
  5.                 $sql.=' WHERE uid=:uid ORDER BY created_date_time';
  6.         }
  7.         $stm = $this->pdo->prepare($sql);
  8.         if($uid){
  9.             $stm->bindParam(':uid', $uid);
  10.         }
  11.         if ($stm->execute()){
  12.             return $stm->fetchAll(PDO::FETCH_OBJ);
  13.         }
  14.     }
  15.     return false;
  16. }
The getComments(...) method above issues a select Sql statement that will return either all comments or comments with a specific uid. If you have several pages that need comments, you can assign a uid to each page. When retrieving the comments, you can use the uid assigned for each page and for admin purposes you can omit the uid parameter to return all comments.

Finally we need a delete method, for admin purposes. Listing 1.5 below shows the complete code.

Listing 1.5

  1. class CommentManager {
  2.     private $pdo = null;
  3.     public function __construct($host, $dbname, $username, $password){
  4.         $this->pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
  5.         $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  6.     }
  7.     public function addComment($fullName, $comment, $uid = null){
  8.         if ($this->pdo){
  9.             $stm = $this->pdo->prepare("INSERT INTO comments (full_name,comment,uid,created_date_time) VALUES (:full_name,:comment,:uid,NOW())");
  10.             $stm->bindParam(':full_name', $fullName);
  11.             $stm->bindParam(':comment', $comment);
  12.             $stm->bindParam(':uid', $uid);
  13.             if ($stm->execute()){
  14.                 return true;
  15.             }
  16.         }
  17.         return false;
  18.     }
  19.     public function getComments($uid=null){
  20.         if ($this->pdo){
  21.             $sql = 'SELECT * FROM comments ';
  22.             if($uid){
  23.                 $sql.=' WHERE uid=:uid ORDER BY created_date_time';
  24.             }
  25.             $stm = $this->pdo->prepare($sql);
  26.             if($uid){
  27.                 $stm->bindParam(':uid', $uid);
  28.             }
  29.             if ($stm->execute()){
  30.                 return $stm->fetchAll(PDO::FETCH_OBJ);
  31.             }
  32.         }
  33.         return false;
  34.     }
  35.     public function deleteCommentById($id){
  36.         if ($this->pdo){
  37.             $stm = $this->pdo->prepare("DELETE FROM comments WHERE id=:id");
  38.             $stm->bindParam(':id', $id);
  39.             if ($stm->execute()){
  40.                 return true;
  41.             }
  42.         }
  43.         return false;
  44.     }
  45. }
The class is now ready to be tested. The final listing 1.6 below shows a simple test case.

Listing 1.6

  1. try{
  2.     $cm = new CommentManager('localhost', 'dbname', 'root', '');
  3.     // Add a new comment
  4.     $cm->addComment('John Doe', 'This is my first post','uid123456');
  5.     // Get all comments
  6.     $comments = $cm->getComments();
  7.     // Get all comments by uid
  8.     $comments = $cm->getComments('uid123456');
  9.     // Delete comment by comment id
  10.     $cm->deleteCommentById(1);
  11. }catch(PDOException $e){
  12.     // Print error message
  13.     echo $e->getMessage();
  14. }

The final part of the coding requires a simple form to allow a user to post comments and a comments view to read all comments but that wont be covered in this tutorial. This brings me to the end of this tutorial. Please leave any comments that can help improve this tutorial.

No comments:

Post a Comment