Like Dislike Rating System with jQuery, Ajax and PHP

The rating system is very helpful to know what the audience think about your idea. Not only the idea but also the user can rate different products or services. Rating helps the user to give their thought and differentiate how good or bad a products or service is. Also, it helps the owner to understand the drawbacks of products and know whether the product meets customer expectations or not.

If you want to get the customer feedback, the rating system is very useful. Through the rating system, web admin can track the visitor’s like and dislike. Also, it will help webmaster to understand the visitor’s choices and make their website more interactive with the visitors. Most of the e-commerce websites or blogs implement the rating system to obtain customer or audience review.

The rating system functionality can be easily implemented using jQuery and PHP. In this tutorial, we will show you how to build a simple rating system using jQuery, Ajax, PHP, and MySQL. The example rating system takes the visitor’s like or dislike with jQuery and Ajax. Also, the rating data is stored in the database using PHP and MySQL. Once the total number of likes and dislikes is calculated, it will be displayed to the visitors. We will make the whole process simple and you can implement the rating system in your project very easily.

The OOP concept in PHP will be used to make the whole script lightweight, simple and easy to extend. The following functionality will be implemented in the like dislike rating system using PHP.

  • Fetch the posts data from the database and list with like and dislike button.
  • By clicking on the like and dislike button, the like or dislike number of the particular post will be updated.
  • The like and dislike number will be shown beside the button.

Create Database Table

To store the post data, a table needs to be created in the database and two fields needed to holds the like and dislike number. The following SQL creates a posts table with some basic fields in the MySQL database.

CREATE TABLE `posts` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `content` text COLLATE utf8_unicode_ci NOT NULL,
 `image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `like_num` bigint(10) NOT NULL,
 `dislike_num` bigint(10) NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 `status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1' COMMENT '1=Active, 0=Inactive',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Post Class (Post.class.php)

The Post class handles all the operations related to the database. For example, connect to the MySQL database server, insert, update, and delete post data in the database. Specify the database host ($dbHost), username ($dbUsername), password ($dbPassword), and name ($dbName) as per your database server credentials.

  • __constructor() – Connect to the MySQL database.
  • getRows() – Fetch records from the posts table and returns the post data as an array based on the specified conditions.
  • insert() – Insert post data in the posts table.
  • update() – Update post data in the posts table.
<?php
/*
 * Post Class
 * This class is used for database related (connect, insert, and update) operations
 * @author    CodexWorld.com
 * @url        http://www.codexworld.com
 * @license    http://www.codexworld.com/license
 */
class Post{
    private 
$dbHost     "localhost";
    private 
$dbUsername "root";
    private 
$dbPassword "root";
    private 
$dbName     "codexworld";
    private 
$tblName    "posts";
    
    public function 
__construct(){
        if(!isset(
$this->db)){
            
// Connect to the database
            
$conn = new mysqli($this->dbHost$this->dbUsername$this->dbPassword$this->dbName);
            if(
$conn->connect_error){
                die(
"Failed to connect with MySQL: " $conn->connect_error);
            }else{
                
$this->db $conn;
            }
        }
    }
    
    
/*
     * Returns rows from the database based on the conditions
     * @param string name of the table
     * @param array select, where, order_by, limit and return_type conditions
     */
    
public function getRows($conditions = array()){
        
$sql 'SELECT ';
        
$sql .= array_key_exists("select",$conditions)?$conditions['select']:'*';
        
$sql .= ' FROM '.$this->tblName;
        if(
array_key_exists("where",$conditions)){
            
$sql .= ' WHERE ';
            
$i 0;
            foreach(
$conditions['where'] as $key => $value){
                
$pre = ($i 0)?' AND ':'';
                
$sql .= $pre.$key." = '".$value."'";
                
$i++;
            }
        }
        
        if(
array_key_exists("order_by",$conditions)){
            
$sql .= ' ORDER BY '.$conditions['order_by']; 
        }
        
        if(
array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
            
$sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit']; 
        }elseif(!
array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
            
$sql .= ' LIMIT '.$conditions['limit']; 
        }
        
        
$result $this->db->query($sql);
        
        if(
array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){
            switch(
$conditions['return_type']){
                case 
'count':
                    
$data $result->num_rows;
                    break;
                case 
'single':
                    
$data $result->fetch_assoc();
                    break;
                default:
                    
$data '';
            }
        }else{
            if(
$result->num_rows 0){
                while(
$row $result->fetch_assoc()){
                    
$data[] = $row;
                }
            }
        }
        return !empty(
$data)?$data:false;
    }
    
    
/*
     * Insert data into the database
     * @param string name of the table
     * @param array the data for inserting into the table
     */
    
public function insert($data){
        if(!empty(
$data) && is_array($data)){
            
$columns '';
            
$values  '';
            
$i 0;
            if(!
array_key_exists('created',$data)){
                
$data['created'] = date("Y-m-d H:i:s");
            }
            if(!
array_key_exists('modified',$data)){
                
$data['modified'] = date("Y-m-d H:i:s");
            }
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$columns .= $pre.$key;
                
$values  .= $pre."'".$val."'";
                
$i++;
            }
            
$query "INSERT INTO ".$this->tblName." (".$columns.") VALUES (".$values.")";
            
$insert $this->db->query($query);
            return 
$insert?$this->db->insert_id:false;
        }else{
            return 
false;
        }
    }
    
    
/*
     * Update data into the database
     * @param string name of the table
     * @param array the data for updating into the table
     * @param array where condition on updating data
     */
    
public function update($data,$conditions){
        if(!empty(
$data) && is_array($data)){
            
$colvalSet '';
            
$whereSql '';
            
$i 0;
            if(!
array_key_exists('modified',$data)){
                
$data['modified'] = date("Y-m-d H:i:s");
            }
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$colvalSet .= $pre.$key."='".$val."'";
                
$i++;
            }
            if(!empty(
$conditions)&& is_array($conditions)){
                
$whereSql .= ' WHERE ';
                
$i 0;
                foreach(
$conditions as $key => $value){
                    
$pre = ($i 0)?' AND ':'';
                    
$whereSql .= $pre.$key." = '".$value."'";
                    
$i++;
                }
            }
            
$query "UPDATE ".$this->tblName." SET ".$colvalSet.$whereSql;
            
$update $this->db->query($query);
            return 
$update?$this->db->affected_rows:false;
        }else{
            return 
false;
        }
    }
}
?>

Posts with Like Dislike Rating (index.php)

In the index.php file, all the posts will be fetched from the database and listed with like and dislike button for rating.

JavaScript Code:
This example uses jQuery and Ajax to save rating in the database without page refresh, so include the jQuery library.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

cwRating() is a custom JavaScript function that sends the post ID and rating type to the rating.php file via AJAX. Based on the Ajax response, show the rating number on the like or dislike counter.

<script>
/**
 * cwRating() function sends a request to the server-side
 * to insert like or dislike number in the database.
 * On success, shows the rating number count to the specified element.  
 *
 * Author: CodexWorld
 * 
 * @param id - Unique ID to save like or dislike for this respective ID.
 * @param type - Use 1 for like and 0 for dislike.
 * @param target - The div ID where the total number of likes or dislikes will display.
 * 
 */
function cwRating(id,type,target){
    $.ajax({
        type:'POST',
        url:'rating.php',
        data:'id='+id+'&type='+type,
        success:function(msg){
            if(msg == 'err'){
                alert('Some problem occured, please try again.');
            }else{
                $('#'+target).html(msg);
            }
        }
    });
}
</script>

PHP & HTML Code
Initially, the posts data is retrieved from the database using Post class and listed with some basic details and like & dislike buttons. On clicking the rating buttons, cwRating() function is triggered and pass these parameters – post ID, rating type(1=Like, 0=Dislike), HTML element to show the counter.

<?php
// Load and initialize post class
require_once 'Post.class.php';
$post = new Post();

// Get posts data
$posts $post->getRows();
?> <div class="row"> <?php if(!empty($posts)){ foreach($posts as $row){ ?> <div class="col-sm-4 col-lg-4 col-md-4"> <div class="thumbnail"> <img src="<?php echo 'images/'.$row['image']; ?>" /> <div class="caption"> <h4><?php echo $row['title']; ?></h4> <p><?php echo $row['content']; ?></p> </div> <div class="ratings"> <p class="pull-right"></p> <p> <!-- Like button --> <span class="glyphicon glyphicon-thumbs-up" onClick="cwRating(<?php echo $row['id']; ?>, 1, 'like_count<?php echo $row['id']; ?>')"></span>&nbsp; <!-- Like counter --> <span class="counter" id="like_count<?php echo $row['id']; ?>"><?php echo $row['like_num']; ?></span>&nbsp;&nbsp;&nbsp; <!-- Dislike button --> <span class="glyphicon glyphicon-thumbs-down" onClick="cwRating(<?php echo $row['id']; ?>, 0, 'dislike_count<?php echo $row['id']; ?>')"></span>&nbsp; <!-- Dislike counter --> <span class="counter" id="dislike_count<?php echo $row['id']; ?>"><?php echo $row['dislike_num']; ?></span> </p> </div> </div> </div> <?php } } ?> </div>

Like/Dislike Rating Number Counter (rating.php)

The rating.php file handles following functionality to save rating number in the database.

  • Receive post ID from Ajax request using $_POST in PHP.
  • Fetch post data from the database based on the post ID using getRows() method of Post class.
  • Update like or dislike number based on the rating type ($_POST['type']) using update() method of Post class.
  • Return the like or dislike number to the success function of Ajax request.
<?php
// Load and initialize post class
require_once 'Post.class.php';
$post = new Post();

if(!empty(
$_POST['id'])){
    
    
// Get post data
    
$conditions['where'] = array(
        
'id' => $_POST['id']
    );
    
$conditions['return_type'] = 'single';
    
$postData $post->getRows($conditions);
    
    
// Post total likes
    
$postLike $postData['like_num'];
    
    
// Post total dislikes
    
$postDislike $postData['dislike_num'];
    
    
// Calculates the numbers of like or dislike
    
if($_POST['type'] == 1){
        
$like_num = ($postLike 1);
        
$upData = array(
            
'like_num' => $like_num
        
);
        
$return_count $like_num;
    }else{
        
$dislike_num = ($postDislike 1);
        
$upData = array(
            
'dislike_num' => $dislike_num
        
);
        
$return_count $dislike_num;
    }
    
    
// Update post like or dislike
    
$condition = array('id' => $_POST['id']);
    
$update $post->update($upData$condition);
    
    
// Return like or dislike number if update is successful, otherwise return error
    
echo $update?$return_count:'err';
}
?>

Star rating system with jQuery, Ajax and PHP

Styling

In the example code, Bootstrap library is used to style the posts list and Like/Dislike buttons. You can omit it if you don’t want to use Bootstrap.

Include the Bootstrap CSS and JS library.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

Specify some CSS code for styling the posts list and Like/Dislike buttons.

.row{ margin:20px 20px 20px 20px;}
.ratings{ font-size:25px !important;}
.thumbnail img {
    width: 100%;
}
.ratings {
    padding-right: 10px;
    padding-left: 10px;
    color: #d17581;
}
.thumbnail {
    padding: 0;
}
.thumbnail .caption-full {
    padding: 9px;
    color: #333;
}
.glyphicon-thumbs-up:hover{ color:#008000; cursor:pointer;}
.glyphicon-thumbs-down:hover{ color: #E10000; cursor:pointer;}
.counter{ color:#333333;}
.thumbnail img{height:200px;}

Conclusion

Here we have tried to make rating system simple and user-friendly. Using our example script, you can easily implement rating system in PHP with jQuery and Ajax. As per this example script a user can rate multiple times for the same item. If you want to restrict the user from multiple times rating, you can do it in two ways.

  • Allow the user to vote after login. Here you can easily track User Id and allow the user to vote only once.
  • Track the user IP address using $_SERVER['REMOTE_ADDR'] and allow the user to vote only once.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

16 Comments

  1. Ruben Said...
  2. Ritesh Kumar Singh Said...
    • CodexWorld Said...
  3. Mark Said...
  4. Melissa Said...
  5. Jasmin Said...
  6. Grantoos Said...
  7. Ainz Ooal Gown Said...
    • CodexWorld Said...
  8. Devil Said...
  9. Florian Said...
  10. Abay Said...
  11. Anshul Singh Chouhan Said...
  12. Kris Said...
  13. Jason Said...
    • CodexWorld Said...

Leave a reply

keyboard_double_arrow_up