Hello i want to make notification when new message is received, i have a row seen with values 0 and 1 if is 0 then its unread else is seen i got this code but when it displays the output shows the number of rows but for example i have 3 uread messages it displays 111 and not just 3 i tried with strlen to get the value but i cant please any help ?

function check_messages() {
        global $conn;
        $user = getUserData('users', 'UserUsername');
        $sql = "SELECT seen FROM ticket WHERE receiverName='{$user}'";
        $result = $conn->query($sql);

        $count = 0;

        if(!$result){
            echo "Problem!";
            trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
        } else {
            if($result->num_rows > 0) {
                $count++;
                $num_length = strlen((int)$count);
                while($row = $result->fetch_assoc()){
                    $seen = $row["seen"];

                    if($seen == '0'){
                        echo $num_length;
                    }
                }
            }
        }
        $conn->close();
    }

Dani AI

Generated

Short diagnosis: the loop was echoing a value on every row and strlen((int)$count) was returning the number of characters (always 1 for small counts), so three unread rows printed as "111". called out the strlen/loop symptom and showed the correct approach: increment a counter while iterating and echo once after the loop — but an even simpler, more efficient solution is to let the database count unread messages.

Use a COUNT(*) query with a prepared statement (prevents SQL injection and avoids fetching every row):

$stmt = $conn->prepare(
  "SELECT COUNT(*) AS unread FROM ticket WHERE receiverName = ? AND seen = 0"
);
$stmt->bind_param('s', $user);
$stmt->execute();
$stmt->bind_result($unread);
$stmt->fetch();
$stmt->close();

echo (int)$unread;

PDO equivalent:

$stmt = $pdo->prepare(
  "SELECT COUNT(*) FROM ticket WHERE receiverName = :u AND seen = 0"
);
$stmt->execute([':u' => $user]);
$unread = (int)$stmt->fetchColumn();
echo $unread;

Practical tips and cautions:

  • Make sure seen is stored as a numeric type (TINYINT/BOOLEAN) so comparisons are reliable and fast.
  • Add an index on (receiverName, seen) to keep COUNT queries cheap on large tables.
  • Don’t close a shared DB connection inside a small helper function; let the application lifecycle manage it.
  • For UI badges, cast to int and consider capping display (e.g., show "99+").
  • For high-frequency polling, either cache the count or push notifications rather than querying every few seconds.

These changes fix the repeated-echo bug and turn the operation into a single, fast query suitable for production.

Recommended Answers

All 5 Replies

the way you are using strlen it is returning the length of your count ie strlen(0) = 1
since strlen will always be 1 (till count > 9)
and your echo is in your loop its outputting 1 then 1 then 1

oh okay but how should i output the number 3 itself.

        if($result->num_rows > 0) {
            $count++;

that says whatever the number of rows, $count now equals one, unless there are no rows, in which case $count is still zero. Then you are doing this.

            $num_length = strlen((int)$count);
            while($row = $result->fetch_assoc()){
                $seen = $row["seen"];
                if($seen == '0'){
                    echo $num_length;
                }

so now $num-length has a value of one (the number of characters in $count, which always has a value of 1 in this loop or zero if there are no rows and the loop is not executed), nothing to do with the number of times $seen is >0
And then you just keep echoing that value of $num-length, which is always one, because it is never incremented inside your loop! And neither is $count incremented.
You are NOT counting anything at all to do with $seen !

Drop the first appearance of $count++, and all your bits about $num-length, then use something like this

             while($row = $result->fetch_assoc()){
                $seen = $row["seen"];
                if($seen == '0'){
                    $count++
                }
                echo $count;

So here you are echoing the count of the number of times $seen is zero, after you have worked through the list of results. You were originally echoing a value every time you had $seen >0, instead of counting them all and echoing the answer.

PS I can't be bothered counting through the closing brackets to place echo $count at exactly the right place, so it might be later in your code. Try moving it down one closing bracket at a time yourself if it doesn't appear or appears several times.

Thank you very much :)

here is the final result

function check_messages() {
        global $conn;
        $user = getUserData('users', 'UserUsername');
        $sql = "SELECT seen FROM ticket WHERE receiverName='{$user}'";
        $result = $conn->query($sql);

        $count = 0;

        if(!$result){
            echo "Problem!";
            trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
        } else {
            if($result->num_rows > 0) {
                //(int)$count++;
                //$num_length = strlen((int)$count);
                while($row = $result->fetch_assoc()){
                    $seen = $row["seen"];

                    if($seen == '0'){
                        $count++;
                    }
                }
                echo $count;
            }
        }
        //$conn->close();
    }
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.