PHP Comments System with Like Unlike

by Vincy. Last modified on January 18th, 2024.

Many social media websites like Facebook have the options to add like unlike for the posts, links, photos added by the user. Adding likes and unlikes using AJAX will give a good user experience.

It can be used effectively to filter and sort content. Sometimes, it can also be used to identify weeds out of the comments.

This comments system allows the user to add comments and to add replies to a particular comment added by some other user. Each comment and reply, it contains a thumb icon that is shown to the user to add likes for the comments and replies.

Initially, all the icons are in grey will represent that the comments and the replies have not yet been liked by the user. Once the user liked a comment by clicking the grey icon, then it turns to blue to update the status and the like count will also be updated.

The screenshot shows the output for the PHP comments system with like unlike. The liked comments are highlighted with the blue thumb icon, whereas grey thumbs are used as default.

php-comment-system-with-like-unlike

List Comments with Like Unlike Status and Count

This code is for getting the comments list and its likes from the database. Each comment and reply row shows the like, unlike added by the current user. Also, it shows the total likes count of each record. The code is,

comment-list.php

<?php
require_once("db.php");

$memberId = 1;

$sql = "SELECT tbl_comment.*, tbl_like_unlike.like_unlike FROM tbl_comment
        LEFT JOIN tbl_like_unlike ON tbl_comment.comment_id = tbl_like_unlike.comment_id
        AND member_id = ?
        ORDER BY parent_comment_id ASC, comment_id ASC";

$stmt = mysqli_prepare($conn, $sql);

mysqli_stmt_bind_param($stmt, "i", $memberId);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

$record_set = array();
while ($row = mysqli_fetch_assoc($result)) {
    array_push($record_set, $row);
}

mysqli_free_result($result);
mysqli_stmt_close($stmt);

mysqli_close($conn);

echo json_encode($record_set);
?>

The following script calls PHP via AJAX to list comments with the likes unlikes count. It highlights the up/down thumb icons based on the like-state of a particular comment record.

In the jQuery document.ready() function, the listComment() AJAX method is called.

$(document).ready(function () {
    listComment();
});

// Function to list comments on the page
function listComment() {
    // Make a POST request to get comment data from the server
    $.post("comment-list.php", function (data) {
        // Parse the JSON data received from the server
        var data = JSON.parse(data);

        var comments = "";
        var replies = "";
        var item = "";
        var parent = -1;
        var results = new Array();

        // Create an unordered list to store comments with a specific class
        var list = $("<ul class='outer-comment'>");
        var item = $("<li>").html(comments);

        // Loop through the comment data
        for (var i = 0; (i < data.length); i++) {
            // Get the comment ID and parent comment ID from the data
            var commentId = data[i]['comment_id'];
            parent = data[i]['parent_comment_id'];

            // Retrieve likes and dislikes information for the comment
            var obj = getLikesUnlikes(commentId);

            // Check if the comment is a top-level comment (parent comment)
            if (parent == "0") {
                // Determine the like and dislike icons based on the comment data
                if (data[i]['like_unlike'] >= 1) {
                    like_icon = "<img src='like.png'  id='unlike_" + data[i]['comment_id'] + "' class='like-unlike'  onClick='likeOrDislike(" + data[i]['comment_id'] + ",-1)' />";
                    like_icon += "<img style='display:none;' src='unlike.png' id='like_" + data[i]['comment_id'] + "' class='like-unlike' onClick='likeOrDislike(" + data[i]['comment_id'] + ",1)' />";
                } else {
                    like_icon = "<img style='display:none;' src='like.png'  id='unlike_" + data[i]['comment_id'] + "' class='like-unlike'  onClick='likeOrDislike(" + data[i]['comment_id'] + ",-1)' />";
                    like_icon += "<img src='unlike.png' id='like_" + data[i]['comment_id'] + "' class='like-unlike' onClick='likeOrDislike(" + data[i]['comment_id'] + ",1)' />";
                }

                // Build the HTML structure for displaying the comment
                comments = "\
                    <div class='comment-row'>\
                        <div class='comment-info'>\
                            <span class='commet-row-label'>from</span>\
                            <span class='posted-by'>" + data[i]['comment_sender_name'] + "</span>\
                            <span class='commet-row-label'>at</span> \
                            <span class='posted-at'>" + data[i]['date'] + "</span>\
                        </div>\
                        <div class='comment-text'>" + data[i]['comment'] + "</div>\
                        <div>\
                            <a class='btn-reply' onClick='postReply(" + commentId + ")'>Reply</a>\
                        </div>\
                        <div class='post-action'>\ " + like_icon + "&nbsp;\
                            <span id='likes_" + commentId + "'> " + totalLikes + " likes </span>\
                        </div>\
                    </div>";

                // Create a list item for the comment and append it to the list
                var item = $("<li>").html(comments);
                list.append(item);

                // Create a nested unordered list for replies
                var reply_list = $('<ul>');
                item.append(reply_list);

                // Recursively list replies for the current comment
                listReplies(commentId, data, reply_list);
            }
        }

        // Update the HTML content of the specified element with the list of comments
        $("#output").html(list);
    });
}

function listReplies(commentId, data, list) {

    for (var i = 0; (i < data.length); i++)
    {

        var obj = getLikesUnlikes(data[i].comment_id);
        if (commentId == data[i].parent_comment_id)
        {
            if(data[i]['like_unlike'] >= 1) 
            {
                like_icon = "<img src='like.png'  id='unlike_" + data[i]['comment_id'] + "' class='like-unlike'  onClick='likeOrDislike(" + data[i]['comment_id'] + ",-1)' />";
                like_icon += "<img style='display:none;' src='unlike.png' id='like_" + data[i]['comment_id'] + "' class='like-unlike' onClick='likeOrDislike(" + data[i]['comment_id'] + ",1)' />";
                
            }
            else
            {
                like_icon = "<img style='display:none;' src='like.png'  id='unlike_" + data[i]['comment_id'] + "' class='like-unlike'  onClick='likeOrDislike(" + data[i]['comment_id'] + ",-1)' />";
                like_icon += "<img src='unlike.png' id='like_" + data[i]['comment_id'] + "' class='like-unlike' onClick='likeOrDislike(" + data[i]['comment_id'] + ",1)' />";
                
            }
            var comments = "\
                            <div class='comment-row'>\
                                <div class='comment-info'>\
                                    <span class='commet-row-label'>from</span>\
                                    <span class='posted-by'>" + data[i]['comment_sender_name'] + "</span>\
                                    <span class='commet-row-label'>at</span> \
                                    <span class='posted-at'>" + data[i]['date'] + "</span>\
                                </div>\
                                <div class='comment-text'>" + data[i]['comment'] + "</div>\
                                <div>\
                                    <a class='btn-reply' onClick='postReply(" + data[i]['comment_id'] + ")'>Reply</a>\
                                </div>\
                                <div class='post-action'> " + like_icon + "&nbsp;\
                                    <span id='likes_" + data[i]['comment_id'] + "'> " + totalLikes + " likes </span>\
                                </div>\
                            </div>";

            var item = $("<li>").html(comments);
            var reply_list = $('<ul>');
            list.append(item);
            item.append(reply_list);
            listReplies(data[i].comment_id, data, reply_list);
        }
    }
}

This example is an advanced tool that can be used in a real-time application. Because, it has comments add and list features with listing its replies and also with like/unlike voting mechanism.

Get Likes Unlikes of the listed comments

This PHP endpoint receives the comment_id via AJAX and computes the summation of the total likes and unlikes count.

get-like-unlike.php

<?php
require_once("db.php");

$commentId = $_POST['comment_id'];
$totalLikes = "No ";

$likeQuery = "SELECT SUM(like_unlike) AS likesCount FROM tbl_like_unlike WHERE comment_id=?";
$stmt = mysqli_prepare($conn, $likeQuery);

mysqli_stmt_bind_param($stmt, "i", $commentId);

mysqli_stmt_execute($stmt);

$resultLikeQuery = mysqli_stmt_get_result($stmt);

$fetchLikes = mysqli_fetch_array($resultLikeQuery, MYSQLI_ASSOC);

if (isset($fetchLikes['likesCount'])) {
    $totalLikes = $fetchLikes['likesCount'];
}

mysqli_stmt_close($stmt);

echo $totalLikes;
?>

Like Unlike Comments via jQuery AJAX

While adding or unsetting the likes, an AJAX call is sent to the PHP to update the like status in the database. I have created tbl_like_unlike to store the comments like, unlike status.

In this table, the likes and the unlikes are stored as 1, -1  respectively. The likes, unlikes are stored with the reference of the corresponding comment_id for which the user added the likes.

comment-like-unlike.php

<?php
require_once("db.php");

$memberId = 1;
$commentId = $_POST['comment_id'];
$likeOrUnlike = 0;

if ($_POST['like_unlike'] == 1) {
    $likeOrUnlike = $_POST['like_unlike'];
}

$selectQuery = "SELECT * FROM tbl_like_unlike WHERE comment_id=? AND member_id=?";
$selectStmt = mysqli_prepare($conn, $selectQuery);
mysqli_stmt_bind_param($selectStmt, "ii", $commentId, $memberId);
mysqli_stmt_execute($selectStmt);
$result = mysqli_stmt_get_result($selectStmt);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);

if (!empty($row)) {
    $updateQuery = "UPDATE tbl_like_unlike SET like_unlike=? WHERE comment_id=? AND member_id=?";
    $updateStmt = mysqli_prepare($conn, $updateQuery);
    mysqli_stmt_bind_param($updateStmt, "iii", $likeOrUnlike, $commentId, $memberId);
    mysqli_stmt_execute($updateStmt);
} else {
    $insertQuery = "INSERT INTO tbl_like_unlike (member_id, comment_id, like_unlike) VALUES (?, ?, ?)";
    $insertStmt = mysqli_prepare($conn, $insertQuery);
    mysqli_stmt_bind_param($insertStmt, "iii", $memberId, $commentId, $likeOrUnlike);
    mysqli_stmt_execute($insertStmt);
}

mysqli_stmt_close($selectStmt);
if (isset($updateStmt)) {
    mysqli_stmt_close($updateStmt);
}
if (isset($insertStmt)) {
    mysqli_stmt_close($insertStmt);
}

$totalLikes = "No ";
$likeQuery = "SELECT SUM(like_unlike) AS likesCount FROM tbl_like_unlike WHERE comment_id=?";
$likeStmt = mysqli_prepare($conn, $likeQuery);
mysqli_stmt_bind_param($likeStmt, "i", $commentId);
mysqli_stmt_execute($likeStmt);
$resultLikeQuery = mysqli_stmt_get_result($likeStmt);
$fetchLikes = mysqli_fetch_array($resultLikeQuery, MYSQLI_ASSOC);

if (isset($fetchLikes['likesCount'])) {
    $totalLikes = $fetchLikes['likesCount'];
}

mysqli_stmt_close($likeStmt);

echo $totalLikes;
?>

All AJAX handlers to initiate like/unlike with a comment system

These PHP files are accessed by jQuery AJAX script. The AJAX will receive the JSON response sent from the PHP code and parse the result to update the UI. In the PHP code, the JSON data format is prepared by using json_encode() function.

If you are looking for a detailed tutorial on JSON handling with PHP visit the linked article which will be more informative with easy examples.

The AJAX functions are,

// Function to retrieve the number of likes for a comment
function getLikesUnlikes(commentId) {
    // Make an AJAX request to the server to get like and unlike data
    $.ajax({
        type: 'POST',                  // HTTP method for the request
        async: false,                  // Synchronous request (blocking)
        url: 'get-like-unlike.php',    // URL to the server-side script
        data: { comment_id: commentId }, // Data to be sent to the server
        success: function (data) {
            // Set the totalLikes variable based on the server response
            totalLikes = data;
        }
    });
}

// Function to handle liking or disliking a comment
function likeOrDislike(comment_id, like_unlike) {
    // Make an AJAX request to the server for handling like or dislike
    $.ajax({
        url: 'comment-like-unlike.php',   // URL to the server-side script
        async: false,                      // Synchronous request (blocking)
        type: 'post',                      // HTTP method for the request
        data: { comment_id: comment_id, like_unlike: like_unlike }, // Data to be sent to the server
        dataType: 'json',                  // Expected data type of the server response
        success: function (data) {
            // Update the displayed likes count with the server response
            $("#likes_" + comment_id).text(data + " likes");

            // Update the display based on the like or dislike action
            if (like_unlike == 1) {
                $("#like_" + comment_id).css("display", "none");
                $("#unlike_" + comment_id).show();
            }

            if (like_unlike == -1) {
                $("#unlike_" + comment_id).css("display", "none");
                $("#like_" + comment_id).show();
            }
        },
        error: function (data) {
            // Display an alert in case of an error with the AJAX request
            alert("error : " + JSON.stringify(data));
        }
    });
}
function getLikesUnlikes(commentId)
{
    $.ajax({
        type: 'POST',
        async: false,
        url: 'get-like-unlike.php',
        data: {comment_id: commentId},
        success: function (data)
        {
            totalLikes = data;
        }

    });
}

Add more comments to the database

The SQL script given in the downloadable source has a few records of comments as initial data. Apart from that, the example code gives to add more comments through the user interface.

$("#submitButton").click(function () {
    $("#comment-message").css('display', 'none');
    var str = $("#frm-comment").serialize();

    // Make an AJAX request to add a comment
    $.ajax({
        url: "comment-add.php",  // URL to the server-side script handling comment addition
        data: str,               // Serialized form data to be sent to the server
        type: 'post',            // HTTP method for the request
        success: function (response) {
            // Parse the JSON response
            var result = eval('(' + response + ')');
            
            // Check if the response is successful
            if (response) {
                // Display the comment message block
                $("#comment-message").css('display', 'inline-block');
                
                // Clear input fields
                $("#name").val("");
                $("#comment").val("");
                $("#commentId").val("");
                
                // Update the list of comments
                listComment();
            } else {
                // Display an alert in case of failure
                alert("Failed to add comments !");
                return false;
            }
        }
    });
});

Thus, we have seen an advanced PHP comments system with replies and likes/unlikes feature. We have learned to implement this via AJAX programming.

Download

Vincy
Written by Vincy, a web developer with 15+ years of experience and a Masters degree in Computer Science. She specializes in building modern, lightweight websites using PHP, JavaScript, React, and related technologies. Phppot helps you in mastering web development through over a decade of publishing quality tutorials.

Comments to “PHP Comments System with Like Unlike”

Leave a Reply

Your email address will not be published. Required fields are marked *

↑ Back to Top

Share this page