当前位置: 首页> 最新文章列表> 为什么 num_rows 返回的是 0?常见误区解析

为什么 num_rows 返回的是 0?常见误区解析

M66 2025-05-31

在 PHP 中,使用 MySQLi 扩展查询数据库时,很多开发者会遇到一个令人困惑的问题: 这到底是怎么回事?本文将带你梳理常见的误区,帮你找出问题的根源。

误区一:使用了 mysqli_multi_query

mysqli_multi_query 是一次可以执行多条 SQL 语句的方法,但它返回的是一个布尔值,真正的结果集要通过 mysqli_store_resultmysqli_use_result 来获取。

示例代码:

<?php
$mysqli = new mysqli("localhost", "user", "password", "database");

$sql = "SELECT * FROM users; SELECT * FROM products;";
if ($mysqli->multi_query($sql)) {
    do {
        if ($result = $mysqli->store_result()) {
            echo "当前结果集行数: " . $result->num_rows . "<br>";
            $result->free();
        }
    } while ($mysqli->more_results() && $mysqli->next_result());
}
?>

如果直接尝试用 multi_query 返回值调用 num_rows,当然会得到 0。确保你正确获取结果集对象。

误区二:忘记执行查询

有些开发者写了 $stmt = $mysqli->prepare(...),然后直接用 $stmt->num_rows,但注意:prepare 并不会执行查询,只是准备。

必须先执行查询并获取结果:

<?php
$stmt = $mysqli->prepare("SELECT * FROM users WHERE age > ?");
$stmt->bind_param("i", $age);
$age = 18;
$stmt->execute();
$result = $stmt->get_result();
echo "行数: " . $result->num_rows;
?>

如果跳过 executeget_resultnum_rows 根本无从谈起。

误区三:使用了 UNBUFFERED 查询

默认情况下,MySQLi 使用缓冲查询,可以直接用 num_rows。但如果用 MYSQLI_USE_RESULT 模式,结果集是流式的,MySQL 无法在未遍历前计算总行数。

示例:

<?php
$result = $mysqli->query("SELECT * FROM users", MYSQLI_USE_RESULT);
echo $result->num_rows; // 错误:此时无法获取行数

解决方法是使用默认的缓冲模式或自己遍历统计。

误区四:误解 num_rows 的含义

很多人误以为 num_rows 可以用在 INSERTUPDATEDELETE 查询上。其实这些操作没有结果集,应该用 $mysqli->affected_rows

<?php
$mysqli->query("UPDATE users SET status = 'active' WHERE last_login > NOW() - INTERVAL 30 DAY");
echo "受影响的行数: " . $mysqli->affected_rows;
?>

记住:只有 SELECT 查询产生的结果集才有 num_rows

小结

如果你遇到 num_rows 总是返回 0,先检查:

? 是不是用的 multi_query 却没取到结果集?
? 是不是 prepare 后忘了 executeget_result
? 是不是用了 UNBUFFERED 模式?
? 是不是搞错了查询类型?

避免这些误区,就能正确使用 mysqli_resultnum_rows,少走弯路。