在 PHP 中,使用 MySQLi 扩展查询数据库时,很多开发者会遇到一个令人困惑的问题: 这到底是怎么回事?本文将带你梳理常见的误区,帮你找出问题的根源。
mysqli_multi_query 是一次可以执行多条 SQL 语句的方法,但它返回的是一个布尔值,真正的结果集要通过 mysqli_store_result 或 mysqli_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;
?>
如果跳过 execute 或 get_result,num_rows 根本无从谈起。
默认情况下,MySQLi 使用缓冲查询,可以直接用 num_rows。但如果用 MYSQLI_USE_RESULT 模式,结果集是流式的,MySQL 无法在未遍历前计算总行数。
示例:
<?php
$result = $mysqli->query("SELECT * FROM users", MYSQLI_USE_RESULT);
echo $result->num_rows; // 错误:此时无法获取行数
解决方法是使用默认的缓冲模式或自己遍历统计。
很多人误以为 num_rows 可以用在 INSERT、UPDATE、DELETE 查询上。其实这些操作没有结果集,应该用 $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 后忘了 execute 和 get_result?
? 是不是用了 UNBUFFERED 模式?
? 是不是搞错了查询类型?
避免这些误区,就能正确使用 mysqli_result 和 num_rows,少走弯路。