skip to Main Content

Am building a website using PHP and MYSQL and got stuck on how to get the number of comments for each individual post. I tried to do something but it was giving me the total number of approved comments for all posts. Instead of the one’s for individual posts as seen in the screenshot below.

Screenshot of the frontend

Here is what i have tried.

MY CODE ON INDEX.PHP

$get_comment = "SELECT * FROM comments WHERE status = 'approve'";
$get_comment_run = mysqli_query($con, $get_comment);
$num_of_rows = mysqli_num_rows($get_comment_run);

if($num_of_rows > 0) {
    echo "<span><i class='fas fa-comments'></i> $num_of_rows</span>";
}
else {
    echo "0";
}

This is my table structure or the create table script for the comment table.

 -- phpMyAdmin SQL Dump
-- version 4.8.0.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Jan 28, 2019 at 12:15 AM
-- Server version: 10.1.32-MariaDB
-- PHP Version: 7.2.5

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `cms`
--

-- --------------------------------------------------------

--
-- Table structure for table `comments`
--

CREATE TABLE `comments` (
  `id` int(11) NOT NULL,
  `date` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `username` varchar(255) NOT NULL,
  `post_id` int(11) NOT NULL,
  `email` varchar(255) NOT NULL,
  `website` varchar(255) NOT NULL,
  `image` varchar(255) NOT NULL,
  `comment` text NOT NULL,
  `status` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `comments`
--

INSERT INTO `comments` (`id`, `date`, `name`, `username`, `post_id`, `email`, `website`, `image`, `comment`, `status`) VALUES
(1, 1548612873, 'Val Amasiatu', 'compus', 47, '[email protected]', 'avidscholars.com.ng', 'Unknown_Member.jpg', 'Cool', 'approve');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `comments`
--
ALTER TABLE `comments`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `comments`
--
ALTER TABLE `comments`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

AND THE SCRIPT FOR THE POST TABLE

-- phpMyAdmin SQL Dump
-- version 4.8.0.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Jan 28, 2019 at 12:19 AM
-- Server version: 10.1.32-MariaDB
-- PHP Version: 7.2.5

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `cms`
--

-- --------------------------------------------------------

--
-- Table structure for table `posts`
--

CREATE TABLE `posts` (
  `id` int(11) NOT NULL,
  `date` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `author` varchar(255) NOT NULL,
  `author_image` varchar(255) NOT NULL,
  `image` varchar(255) NOT NULL,
  `categories` varchar(255) NOT NULL,
  `tags` varchar(255) NOT NULL,
  `post_data` text NOT NULL,
  `views` int(11) NOT NULL,
  `status` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `posts`
--

INSERT INTO `posts` (`id`, `date`, `title`, `author`, `author_image`, `image`, `categories`, `tags`, `post_data`, `views`, `status`) VALUES
(42, 1548346810, 'What is Lorem Ipsum?', '1234', 'AvePoint.jpg', 'administration-balance-blur-272978.jpg', 'tutorials', 'my, my, my', '<p>Accidentally deleted a closing div tag. And have tried all night but couldn't locate it. I have also tried some online tools but without success. I have counted with notepad++ and found 22 and 21 , meaning that one is missing. But what i have not been able to do is to find and place this missing closing tag div where it is supposed to be.</p>rn<p>Accidentally deleted a closing div tag. And have tried all night but couldn't locate it. I have also tried some online tools but without success. I have counted with notepad++ and found 22 and 21 , meaning that one is missing. But what i have not been able to do is to find and place this missing closing tag div where it is supposed to be.</p>rn<p>Accidentally deleted a closing div tag. And have tried all night but couldn't locate it. I have also tried some online tools but without success. I have counted with notepad++ and found 22 and 21 , meaning that one is missing. But what i have not been able to do is to find and place this missing closing tag div where it is supposed to be.</p>', 4, 'publish'),
(43, 1548346917, 'Another test post', '1234', 'AvePoint.jpg', '33754-bible1200-800w-tn.jpg', 'books', 'Testing and observing', '<h2>Before you start</h2>rn<p><strong>Make sure&nbsp;<a href="http://validator.w3.org/">your code is valid</a></strong>, or you could get unexpected results. The script assumes you have valid HTML5 code, but would like to make sure you didn't leave any tags, unintentionally, unclosed.</p>rn<p>This script doesn't check for self closing tags.</p>rn<p>&nbsp;</p>', 3, 'publish'),
(44, 1548352991, 'A unique post', '1234', 'AvePoint.jpg', 'prayer.jpg', 'Themes', 'Testing and useful', '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime, fuga mollitia ducimus error nobis numquam perferendis vitae quam obcaecati similique optio non beatae in voluptas dolores, praesentium, architecto nisi ab. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime, fuga mollitia ducimus error nobis numquam perferendis vitae quam obcaecati similique optio non beatae in voluptas dolores, praesentium, architecto nisi ab.</p>rn<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime, fuga mollitia ducimus error nobis numquam perferendis vitae quam obcaecati similique optio non beatae in voluptas dolores, praesentium, architecto nisi ab. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime, fuga mollitia ducimus error nobis numquam perferendis vitae quam obcaecati similique optio non beatae in voluptas dolores, praesentium, architecto nisi ab.</p>', 4, 'publish'),
(46, 1548353597, 'Guidelines', '1234', 'AvePoint.jpg', 'dove.jpg', 'pro-tips', 'Spirit', '<h2>Before you start</h2>rn<p><strong>Make sure&nbsp;<a href="http://validator.w3.org/">your code is valid</a></strong>, or you could get unexpected results. The script assumes you have valid HTML5 code, but would like to make sure you didn't leave any tags, unintentionally, unclosed.</p>rn<p>This script doesn't check for self closing tags.</p>', 17, 'publish'),
(47, 1548353755, 'Stackoverflow Question', '1234', 'AvePoint.jpg', 'Prayer-Man.jpg', 'pro-tips', 'going, praying', '<p>Accidentally deleted a closing div tag. And have tried all night but couldn't locate it. I have also tried some online tools but without success. I have counted with notepad++ and found 22 and 21 , meaning that one is missing. But what i have not been able to do is to find and place this missing closing tag div where it is supposed to be.</p>rn<p>Accidentally deleted a closing div tag. And have tried all night but couldn't locate it. I have also tried some online tools but without success. I have counted with notepad++ and found 22 and 21 , meaning that one is missing. But what i have not been able to do is to find and place this missing closing tag div where it is supposed to be.</p>', 9, 'publish'),
(48, 1548614342, 'What is Lorem Ipsum?', 'val', 'adult-beard-blur-927022.jpg', 'hero.jpg', 'money', 'come', '<p>The new editor will be enabled by default in the next major release of WordPress. If you&rsquo;re not sure how compatible your current themes and plugins&nbsp; The new editor will be enabled by default in the next major release of WordPress. If you&rsquo;re not sure how compatible your current themes and plugins&nbsp; The new editor will be enabled by default in the next major release of WordPress. If you&rsquo;re not sure how compatible your current themes and plugins&nbsp;The new editor will be enabled by default in the next major release of WordPress. If you&rsquo;re not sure how compatible your current themes and plugins.</p>rn<p>The new editor will be enabled by default in the next major release of WordPress. If you&rsquo;re not sure how compatible your current themes and plugins&nbsp;themes and plugins&nbsp;The new editor will be enabled by default in the next major release of WordPress. If you&rsquo;re not sure how compatible your current themes and plugins.</p>', 2, 'publish');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `posts`
--
ALTER TABLE `posts`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `posts`
--
ALTER TABLE `posts`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=49;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

2

Answers


  1. You need too add to your database table a unique ID for each blog post (if you don’t have already), then when a comment added, while inserting the comment into the database, assign the blog post ID to that comment, and when searching for comments, do :

    $get_comment = "SELECT * FROM comments WHERE post_id = $post_id && status = 'approve'";
    

    $post_id will be the unique ID of the blog post.

    post_id must exist in your database.

    Login or Signup to reply.
  2. There is a missing constraint in your comment table, the field post_id is supposed to be a reference (a FOREIGN KEY) to a specific posts.

    I strongly suggest you to alter the table comment and add this constraint, this will enforce the integrity and help the queries to be executed since the fields will be a reference to an index :

    ALTER TABLE `comments`
    ADD FOREIGN KEY (`post_id`)
    REFERENCES `posts` (`id`);
    -- Make sure to read the part below before adding this constraint to your table.
    

    Doing this will prevent you to delete a post containing comments, you’ll have to delete the comment first, or you can add an action to perform :

    ALTER TABLE `comments`
    ADD FOREIGN KEY (`post_id`)
    REFERENCES `posts` (`id`)
    ON DELETE CASCADE; -- This will delete the comment if a post is deleted
    

    To get the number of comment for each post, you’ll have to use a COUNT statement, combined with a GROUP BY :

    SELECT COUNT(`id`) AS "CommentCount",
           `post_id`
    FROM `comments`
    WHERE `status` = "approve"
    GROUP BY `post_id`;
    

    And then, in your php code :

    $get_comment_run = mysqli_query($con, $get_comment); //$get_comment being, of course, the above query
    
    while ($row = mysqli_fetch_array($get_comment_run, MYSQLI_ASSOC))
    {
        if($row["CommentCount"] > 0)
        {
            echo "<span><i class='fas fa-comments'></i>There is " . $row["CommentCount"] . " comments for the post id " . $row["post_id"] . "</span>";
        }
        else
        {
            echo "0";
        }
    }
    

    Example with simplified datas in the table :

    Schema (MySQL v5.7)

    CREATE TABLE comments
    (
      id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
      text VARCHAR(255),
      `status` VARCHAR(255),
      post_id INT NOT NULL
    );
    
    INSERT INTO comments VALUES (default, "a", "approve", 1),
                                (default, "b", "approve", 1),
                                (default, "c", "approve", 1),
                                (default, "d", "pending", 1),
                                (default, "e", "approve", 1),
                                (default, "f", "rejected", 1), -- 4 approved for post_id 1
                                (default, "a", "approve", 2),
                                (default, "b", "approve", 2),
                                (default, "c", "approve", 2),
                                (default, "d", "pending", 2),
                                (default, "e", "approve", 2), -- 4 approved for post_id 2
                                (default, "f", "rejected", 3),
                                (default, "a", "approve", 3),
                                (default, "b", "approve", 3), -- 2 approved for post_id 3
                                (default, "c", "approve", 4),
                                (default, "d", "pending", 4), -- 1 approved for post_id 4
                                (default, "e", "approve", 5), -- 1 approved for post_id 5
                                (default, "f", "rejected", 6), -- 0 approved for post_id 6
                                (default, "a", "approve", 7),
                                (default, "b", "approve", 7),
                                (default, "c", "approve", 7), -- 3 approved for post_id 7
                                (default, "d", "pending", 8), -- 0 approved for post_id 8
                                (default, "e", "approve", 9), -- 1 approved for post_id 9
                                (default, "f", "rejected", 10);  -- 0 approved for post_id 10
    

    Query #1

    SELECT COUNT(`id`) AS "CommentCount",
           `post_id`
    FROM `comments`
    WHERE `status` = "approve"
    GROUP BY `post_id`;
    

    Output

    | CommentCount | post_id |
    | ------------ | ------- |
    | 4            | 1       |
    | 4            | 2       |
    | 2            | 3       |
    | 1            | 4       |
    | 1            | 5       |
    | 3            | 7       |
    | 1            | 9       |
    

    View on DB Fiddle

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search