Hey Everyone,

I previously had an issue with a date display format. I have a different question that deals with displaying singular or plural words using a version of an if statement that displays an "s" or displays nothing based on how many comments there are in a specific blog post. Here is the function that I've written and I'm afraid it may not be right. Any suggestions?
comments.inc.php

function gather_comments ($pid){
    $pid = (int)$pid;

    $sql = "SELECT * FROM `comments` WHERE `post_id`= {$pid}";

    $comments = mysql_query($sql);

    return $comments;

}

and here is blog_list.php

<h4 style="text-decoration: none;">(<?php echo $post['total_comments']; ?> comment<?php if(gather_comments() !=1){ echo '';}elseif(gather_comments == 0 || 1){echo 's';} ?>, last comment <?php echo $post['last_comment']; ?>)</h4>

basically, I want the word comment to be plural if there are either no or more than one comments in the database and if there are more than one comment in a database, to output the "s" and if there is either 1 to output nothing. This may seem simple to most but It would be very helpful to guide me in the right direction on how to handle this. Thanks in advance!

Recommended Answers

All 16 Replies

Your function is not returning the number of comments but the resource (a special PHP type) for the query. And also the query has to be changed to:

$sql = "SELECT COUNT(*) FROM `comments` WHERE `post_id`= {$pid}";

The function should be something like:

function gather_comments ($pid){
    $pid = (int)$pid;
    $sql = "SELECT COUNT(*) FROM `comments` WHERE `post_id`= {$pid}";

    $res = mysql_query($sql);
    $row = mysqli_fetch_row($res)
    $comments = $row[0];

    return $comments;
}

The logic for displaying singular or plural should be simple:

// call the function only once so you do not shoor too many queries
$commentsCount = gather_comments($pid);

if($commentsCount == 1) {
    echo 'comment';
} else {
    echo 'comments;
}

If you retrieve comments earlier in the script (i.e. for displaying) the function is not necessary since you can just count the retrieved comments.

Member Avatar for diafol

You could even do it in SQL. Not advisable though - I was bored :)

SELECT CONCAT(COUNT(*), " ", IF(COUNT(*) = 1, "comment", "comments")) AS num_comments  FROM comments WHERE post_id = 3
commented: Nice little SQL lesson :-) +9

@broj1, when I did what you suggested, the page went blank instead of what it should have done.

OK, then we have to debug the function.

  1. It is advisable to include error checking with mysql functions (mysql_query, mysqli_fetch_row...). You have to decide how to handle the errors (i.e. the function returning false, stoping the script, custom error messages...).
  2. INclude the checking of the argument value
  3. You can temporary echo the query using die and test it in phpmyadmin
  4. You can echo the resulting row using a combination of die and print_r functions

So considering above, the function should look like:

function gather_comments ($pid){

    // check the argument
    if(is_numeric($pid)) && $pid > 0) {
        $pid = (int)$pid;
    } else {
        return false;
    }

    $sql = "SELECT COUNT(*) FROM `comments` WHERE `post_id`= $pid";

    // DEBUG
    // this is for debugging only, comment it out in production
    // this will display the SQL statement; copy it to phpmyadmin for testing
    die($sql);

    // query the database
    $res = mysql_query($sql);

    // include error checking when queryinig the database
    if(!$res) {

        // DEBUG
        // this is for debugging only, comment it out in production
        die(mysql_error());

        // if error when querying then return false
        return false;
    }

    // fetch the row
    $row = mysqli_fetch_row($res);

    // DEBUG
    // this is for debugging only, comment it out in production
    // this will display what the $row array contains and stop the script
    // the $row array should have only one element ($row[0]) - the count of found comments
    die(print_r($row, 1));        

    // include error checking when fetching the row
    if(!isset($row) || empty($row)) {

        // DEBUG
        // this is for debugging only, comment it out in production
        die('Error counting rows');

        // if error counting rows then return false
        return false;

    } else {

        // everything is OK, get the number of comments and return them
        $comments = $row[0];
        return $comments;
    }
}

Please note that there are debugging statements in the function now. Comment them all out and uncomment one by one testing the function. This way you can check whether the SQL statement has been constructed correctly, the query has been performed successfuly and what the resulting row really contains. You can post the outputs here.

You use the function this way (note the use of htmlspecialchars function to avoid injecting rouge html into script:

$commentsCount = gather_comments($pid);

if(!$commentsCount) {
    echo 'Sory, could not read the database.';
} elseif($commentsCount == 1) {
    echo 'Total ' . htmlspecialchars($post['total_comments']) . 'comment';
} else {
    echo 'Total ' . htmlspecialchars($post['total_comments']) . 'comments ';
}

@broj1, I still have a blank screen after doing what you suggested.

You do not get any errors? What is your php.ini setting for error_reporting and display_errors? It should be set to on for development:

display_errors = on

You can temporary turn error reporting in the script by including this code on the very beginning:

error_reporting(E_ALL);

@broj1, it's set to on.

Can you post the whole code you have. i will test it in my environment.

@Broj1, Here is the blog.list that should display the word comments or comment based on count value in database.

<?php

include('init.php');
include('core/init.inc.php');

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="description" content="" />
<meta name="keywords" content="" />
<title> - Blog List -</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel=”icon” href=”http://completefinancialmgt.com/favicon.ico” type=”image/x-icon” />
<link rel=”shortcut icon” href=”favicon.ico” type=”image/x-icon” />
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body>
<div id="wrapper">
    <?php include 'includes/header.php' ?>
    <div id="menu">
        <?php include 'includes/menu.php' ?>
        <br class="clearfix" />
    </div>
    <div id="splash">
        <img class="pic" src="images/pic01.jpg" width="870" height="230" alt="" />
    </div>
    <div id="page">
        <div id="content"><div class="ic"></div>
            <?php



            $posts = get_posts();

            foreach ($posts as $post){
                ?>
                <h2><a href="blog_read.php?pid=<?php echo $post['id']; ?>"><?php echo $post['title']; ?></a></h2>
                <h4 style="text-decoration: none;">By <?php echo $post['user']; ?> on <?php echo $post['date']; ?></h4>
                <p><?php echo $post['preview']; ?></p>

                <hr />

                <h4 style="text-decoration: none;">(<?php echo $post['total_comments']; ?> <?php $commentsCount = gather_comments($pid);
if($commentsCount == 1) {
    echo 'comment';
} else {
    echo 'comments';
} ?>, last comment <?php echo $post['last_comment']; ?>)</h4>
                <?php
            }

            ?>
        <br class="clearfix" />
        </div>
        <div id="sidebar">
            <?php include 'includes/sidebar.php' ?>
        </div>
        <br class="clearfix" />
    </div>
    <?php include 'includes/bottom_content.php' ?>
</div>
<?php include 'includes/footer.php' ?>
</body>
</html>

And here is the comments.inc.php where the function "gather_comments" is located

<?php

//gets all of the comments for a given blog post
function get_comments($pid){
    $pid = (int)$pid;

    $sql = "SELECT
                `comment_body` AS `body`,
                `comment_user` AS `user`,
                DATE_FORMAT(`comment_date`, '%a., %b %D, %Y %l: %i %p') AS `date`
            FROM `comments`
            WHERE `post_id` = {$pid}";

    $comments = mysql_query($sql);

    $return = array();
    while(($row = mysql_fetch_assoc($comments)) !== false) {
        $return[] = $row;
    }
    return $return;
}

function gather_comments($pid){
    // check the argument
    if(is_numeric($pid)) && $pid > 0) {
        $pid = (int)$pid;
    } else {
        return false;
    }

    $sql = "SELECT COUNT(*) FROM `comments` WHERE `post_id`= $pid";

    // DEBUG
    // this is for debugging only, comment it out in production
    // this will display the SQL statement; copy it to phpmyadmin for testing
    die($sql);

    // query the database
    $res = mysql_query($sql);

    // include error checking when queryinig the database
    if(!$res) {

        // DEBUG
        // this is for debugging only, comment it out in production
        die(mysql_error());

        // if error when querying then return false
        return false;
    }

    // fetch the row
    $row = mysqli_fetch_row($res);

    // DEBUG
    // this is for debugging only, comment it out in production
    // this will display what the $row array contains and stop the script
    // the $row array should have only one element ($row[0]) - the count of found comments
    die(print_r($row, 1));        

    // include error checking when fetching the row
    if(!isset($row) || empty($row)) {

        // DEBUG
        // this is for debugging only, comment it out in production
        die('Error counting rows');

        // if error counting rows then return false
        return false;

    } else {

        // everything is OK, get the number of comments and return them
        $comments = $row[0];
        return $comments;
    }
}

//adds a comment
function add_comment($pid, $user, $body) {
    if (valid_pid($pid) === false) {
        return false;
    }

    $pid    = (int)$pid;
    $user   = mysql_real_escape_string(htmlentities($user));
    $body   = mysql_real_escape_string(nl2br(htmlentities($body)));

    mysql_query("INSERT INTO `comments` (`post_id`, `comment_user`, `comment_body`, `comment_date`) VALUES ({$pid}, '{$user}', '{$body}', NOW())");

    return true;
}

?>

Sorry for the delay. Thanks for any help!

I already have questions that prevent me from carrying on :-)

In your html file there is code on line 34:

$posts = get_posts();

but function get_posts() is not defined in the comments.inc.php file. Is that OK? Can you post the code for this function. The reason for asking is that this function creates a $post array which is supposed to contain a 'total_comments' element (see line 44). If you already have total comments in the array you can use that for singular/plural logic.

Also, where do you get the $pid on line 44.

@broj1, this is where the posts functionality comes into play. (posts.inc.php)

<?php

//checks if the given post id is in the table
function valid_pid($pid) {
    $pid = (int)$pid;

    $total = mysql_query("SELECT COUNT(`post_id`) FROM `posts` WHERE `post_id` = {$pid}");
    $total = mysql_result($total, 0);

    if ($total != 1) {
        return false;
    }else{
        return true;
    }
}

//gets a summary of all blog posts
function get_posts() {
    $sql = "SELECT
                `posts`.`post_id` AS `id`,
                `posts`.`post_title` AS `title`,
                LEFT(`posts`.`post_body`, 512) AS `preview`,
                `posts`.`post_user` AS `user`,
                DATE_FORMAT(`posts`.`post_date`, '%a., %b %D, %Y %l: %i %p') AS `date`,
                `comments`.`total_comments`,
                DATE_FORMAT(`comments`.`last_comment`, '%a., %b %D, %Y %l: %i %p') AS `last_comment`
            FROM `posts`
            LEFT JOIN(
                SELECT
                    `post_id`,
                    COUNT(`comment_id`) AS `total_comments`,
                    MAX(`comment_date`) AS `last_comment`
                FROM `comments`
                GROUP BY `post_id`
            ) AS `comments`
            ON `posts`.`post_id` = `comments`.`post_id`
            ORDER BY `posts`.`post_date` DESC";

    $posts = mysql_query($sql);

 $rows = array();
        while (($row = mysql_fetch_assoc($posts)) !== false) {
                $rows[] = array(
                        'id'                       => $row['id'],
                        'title'                   => $row['title'],
                        'preview'             => $row['preview'],
                        'user'                   => $row['user'],
                        'date'                   => $row['date'],
                        'total_comments' => ($row['total_comments'] === null) ? 0 : $row['total_comments'],
                        'last_comment'     => ($row['last_comment'] === null) ? ' none' : $row['last_comment']
                );
    }

    return $rows;
}

//gets a single post from the table
function get_post($pid) {
    $pid = (int)$pid;

    $sql = "SELECT
                `post_title` AS `title`,
                `post_body` AS `body`,
                `post_user` AS `user`,
                DATE_FORMAT(`post_date`, '%a., %b %D, %Y %l: %i %p') AS `date`
            FROM `posts`
            WHERE `post_id` = {$pid}";

    $post = mysql_query($sql);
    $post = mysql_fetch_assoc($post);

    $post['comments'] = get_comments($pid);

    return $post;
}

//adds a new blog entry
function add_post($name, $title, $body) {
    $name = mysql_real_escape_string(htmlentities($name));
    $title = mysql_real_escape_string(htmlentities($title));
    $body = mysql_real_escape_string(nl2br(htmlentities($body)));

    mysql_query("INSERT INTO `posts` (`post_user`, `post_title`, `post_body`, `post_date`) VALUES ('{$name}', '{$title}', '{$body}', NOW())");
}

?>

I think that's all you need.

Now, if I got it, then you have the number of comments for each post already in the $post['total_comments'] element. In this case you do not need the gather_comments function. Just use the $post['total_comments']:

<h4 style="text-decoration: none;">(<?php echo $post['total_comments']; ?> 
<?php
if($post['total_comments'] == 1) {
echo 'comment';
} else {
echo 'comments';
?>

Correct me if I am wrong.

Wow, I feel dumb. It seriously overlooked that and tried to make things way too complicated. Thank You Broj1! Thanks for helping along with everyone else! That did the trick!

Wait. Now the blog read page wording is wrong..I've tried to fix it in relation to the other page but it won't work the same way. How do I fix this? It's the same issue like with the other page. echoing comments or comment based on number of comments in database.

<?php

include('init.php');
include('core/init.inc.php');

if (isset($_GET['pid'], $_POST['user'], $_POST['body'])) {
    if (add_comment($_GET['pid'], $_POST['user'], $_POST['body'])){
        header("Location: blog_read.php?pid={$_GET['pid']}");
    }else{
        header('Location: blog_list.php');
    }

    die();
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="description" content="" />
<meta name="keywords" content="" />
<title> - Blog -</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel=”icon” href=”http://completefinancialmgt.com/favicon.ico” type=”image/x-icon” />
<link rel=”shortcut icon” href=”favicon.ico” type=”image/x-icon” />
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body>
<div id="wrapper">
    <?php include 'includes/header.php' ?>
    <div id="menu">
        <?php include 'includes/menu.php' ?>
        <br class="clearfix" />
    </div>
    <div id="splash">
        <img class="pic" src="images/pic01.jpg" width="870" height="230" alt="" />
    </div>
    <div id="page">
        <div id="content"><div class="ic"></div>
            <?php

            if (isset($_GET['pid']) === false || valid_pid($_GET['pid']) === false) {
                echo 'Invalid post ID.';
            }else{
                $post = get_post($_GET['pid']);

                ?>
                <h2 style="text-decoration: underline;"><?php echo $post['title']; ?></h2>
                <p>By <?php echo $post['user']; ?> on <?php echo $post['date']; ?> (<?php echo count($post['comments']); ?> <?php if($post['total_comments'] == 1){ echo 'comment';}else{echo 'comments';} ?>, last comment <?php echo $post['last_comment']; ?>)</p>

                <hr />

                <p><?php echo $post['body']; ?></p>

                <hr />
                <h3> There <?php $user_count = user_count(); $suffix2 = ($user_count != 1) ? 'are' : 'is'; echo $suffix2; ?> a total of (<?php $user_count = user_count(); echo count($post['comments']); ?> <?php if($post['total_comments'] == 1){ echo 'comment';}else{echo 'comments';} ?>, last comment <?php echo $post['last_comment']; ?>)</h3>
                <?php

                foreach ($post['comments'] as $comment){
                    ?>
                    <p><?php echo '<div style="display: table-cell; padding-left: 5px; padding-right: 5px; background-color: #E0DCDC; -webkit-border-radius: 30px; -moz-border-radius: 30px; border-radius: 30px;">' . $comment['body'] . '</div>'; ?></p>
                    <p>By <?php echo $comment['user']; ?> on <?php echo $comment['date']; ?></p>
                    <hr />
                    <?php
                }

                ?><br />
                <h3>Leave a Comment:</h3>
                <form action="" method="post">
                    <p>
                        <label for="user">Name</label>
                        <input type="text" name="user" id="user" />
                    </p>
                    <p>
                        Your comment:<br />
                        <textarea name="body" cols="50" rows="5"></textarea>
                    </p>
                    <p>
                        <input type="submit" value="Add Comment!" />
                    </p>
                </form>
                <?php
            }

            ?>
<br class="clearfix" />
        </div>
        <div id="sidebar">
            <?php include 'includes/sidebar.php' ?>
        </div>
        <br class="clearfix" />
    </div>
    <?php include 'includes/bottom_content.php' ?>
</div>
<?php include 'includes/footer.php' ?>
</body>
</html>

This is the accurate one, disregaurd the previous post. This is the one that I cannot get to work right with the same issue I had before.

<?php

include('init.php');
include('core/init.inc.php');

if (isset($_GET['pid'], $_POST['user'], $_POST['body'])) {
    if (add_comment($_GET['pid'], $_POST['user'], $_POST['body'])){
        header("Location: blog_read.php?pid={$_GET['pid']}");
    }else{
        header('Location: blog_list.php');
    }

    die();
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="description" content="" />
<meta name="keywords" content="" />
<title> - Blog - </title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel=”icon” href=”http://completefinancialmgt.com/favicon.ico” type=”image/x-icon” />
<link rel=”shortcut icon” href=”favicon.ico” type=”image/x-icon” />
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body>
<div id="wrapper">
    <?php include 'includes/header.php' ?>
    <div id="menu">
        <?php include 'includes/menu.php' ?>
        <br class="clearfix" />
    </div>
    <div id="splash">
        <img class="pic" src="images/pic01.jpg" width="870" height="230" alt="" />
    </div>
    <div id="page">
        <div id="content"><div class="ic"></div>
            <?php

            if (isset($_GET['pid']) === false || valid_pid($_GET['pid']) === false) {
                echo 'Invalid post ID.';
            }else{
                $post = get_post($_GET['pid']);

                ?>
                <h2 style="text-decoration: underline;"><?php echo $post['title']; ?></h2>
                <p>By <?php echo $post['user']; ?> on <?php echo $post['date']; ?> (<?php $user_count = user_count(); echo count($post['comments']); ?> <?php if($post['total_comments'] == 1){ echo 'comment';}else{echo 'comments';} ?>)</p>

                <hr />

                <p><?php echo $post['body']; ?></p>

                <hr />
                <h3> There <?php $user_count = user_count(); $suffix2 = ($user_count != 1) ? 'are' : 'is'; echo $suffix2; ?> a total of (<?php $user_count = user_count(); echo count($post['comments']); ?> <?php if($post['total_comments'] == 1){ echo 'comment';}else{echo 'comments';} ?>)</h3>
                <?php

                foreach ($post['comments'] as $comment){
                    ?>
                    <p><?php echo '<div style="display: table-cell; padding-left: 5px; padding-right: 5px; background-color: #E0DCDC; -webkit-border-radius: 30px; -moz-border-radius: 30px; border-radius: 30px;">' . $comment['body'] . '</div>'; ?></p>
                    <p>By <?php echo $comment['user']; ?> on <?php echo $comment['date']; ?></p>
                    <hr />
                    <?php
                }

                ?><br />
                <h3>Leave a Comment:</h3>
                <form action="" method="post">
                    <p>
                        <label for="user">Name</label>
                        <input type="text" name="user" id="user" />
                    </p>
                    <p>
                        Your comment:<br />
                        <textarea name="body" cols="50" rows="5"></textarea>
                    </p>
                    <p>
                        <input type="submit" value="Add Comment!" />
                    </p>
                </form>
                <?php
            }

            ?>
<br class="clearfix" />
        </div>
        <div id="sidebar">
            <?php include 'includes/sidebar.php' ?>
        </div>
        <br class="clearfix" />
    </div>
    <?php include 'includes/bottom_content.php' ?>
</div>
<?php include 'includes/footer.php' ?>
</body>
</html>

Sorry again, Ignore the last two posts. I figured it out after medeling with the code. Everything works thanks to broj1 and everyone else who contributed to this issue. You are greatly appreciated!! Solved!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.