PHP中基于SQL行值递增全局变量仅生效一次的问题排查
问题根源
你当前的查询语句用了LIMIT 1,每次只获取数据库中最新的一条记录,导致while循环只会执行一次,变量自然只能递增1次,根本无法累计所有历史数据里的Guest和Intruder数量。
解决方案
推荐两种实现方式,优先选第一种(性能更优):
方案1:直接用SQL统计总数(推荐)
利用数据库的聚合查询直接计算Guest和Intruder的总数量,无需PHP循环遍历所有数据,效率更高。
// 初始化统计变量 $guest = 0; $intruder = 0; // 统计Guest总数 $guestStmt = $db->prepare("SELECT COUNT(*) FROM motion WHERE person = 'Guest'"); $guestStmt->execute(); $guestStmt->bind_result($guest); $guestStmt->fetch(); $guestStmt->close(); // 统计Intruder总数 $intruderStmt = $db->prepare("SELECT COUNT(*) FROM motion WHERE person = 'Intruder'"); $intruderStmt->execute(); $intruderStmt->bind_result($intruder); $intruderStmt->fetch(); $intruderStmt->close(); // 单独获取最新一条记录用于显示 $latestStmt = $db->prepare("SELECT * FROM motion ORDER BY reading_id DESC LIMIT 1"); $latestStmt->execute(); $latestStmt->bind_result($reading_id, $reading_value, $person, $lightlevel, $lightden, $time_detected); $latestStmt->fetch(); // 处理并显示最新记录 $time_parts = explode(" ", $time_detected); $time = date("h:i:sa", strtotime($time_parts[1])); echo "ID: {$reading_id} </br> Reading Value: {$reading_value} </br> Time: {$time} </br> Person: {$person} </br> Lightlevel: {$lightlevel} </br> Lightden: {$lightden}</br>"; echo "<tr><td>" . $person . " </td><td>" . $time . "</td></tr> </br>"; // 输出统计结果 echo "<tr><td>Guest Counter: </td><td>" . $guest . " </td><td>Intruder Counter: </td><td>" . $intruder . "</td></tr>";
方案2:PHP循环所有记录统计
如果一定要用PHP遍历统计,需要去掉LIMIT 1,查询所有记录后循环累加,但数据量大时性能较差。
// 初始化统计变量 $guest = 0; $intruder = 0; $latestRecord = null; // 存储最新一条记录用于单独显示 // 查询所有记录(去掉LIMIT 1) $statement = $db->prepare("SELECT * FROM motion ORDER BY reading_id DESC"); $statement->execute(); $statement->bind_result($reading_id, $reading_value, $person, $lightlevel, $lightden, $time_detected); while($statement->fetch()) { // 统计数量(用elseif避免非Guest/Intruder的值误统计) if ($person == "Guest") { ++$guest; } elseif ($person == "Intruder") { ++$intruder; } // 保存最新一条记录(倒序查询的第一条就是最新的) if (!$latestRecord) { $time_parts = explode(" ", $time_detected); $latestRecord = [ 'id' => $reading_id, 'value' => $reading_value, 'person' => $person, 'lightlevel' => $lightlevel, 'lightden' => $lightden, 'time' => date("h:i:sa", strtotime($time_parts[1])) ]; } } // 显示最新记录 if ($latestRecord) { echo "ID: {$latestRecord['id']} </br> Reading Value: {$latestRecord['value']} </br> Time: {$latestRecord['time']} </br> Person: {$latestRecord['person']} </br> Lightlevel: {$latestRecord['lightlevel']} </br> Lightden: {$latestRecord['lightden']}</br>"; echo "<tr><td>" . $latestRecord['person'] . " </td><td>" . $latestRecord['time'] . "</td></tr> </br>"; } // 输出统计结果 echo "<tr><td>Guest Counter: </td><td>" . $guest . " </td><td>Intruder Counter: </td><td>" . $intruder . "</td></tr>";
额外注意事项
- 你原代码中
echo "Lightden:>存在语法错误,缺少闭合引号和变量引用,已在上述代码中修正。 - 建议用
elseif ($person == "Intruder")替代else,避免数据库中person字段出现其他值时误统计到Intruder中。
内容的提问来源于stack exchange,提问作者AMCode96
相关产品推荐
相关产品推荐

