PHP查询多条数据应避免单次取值,优先用mysqli_fetch_all()或PDO::fetchAll()批量获取;大数据量时须改用while循环流式读取以防内存溢出。

PHP 查询多条数据,核心是别用 mysqli_fetch_row() 或 pdo::fetch() 单次取值,得用循环或批量获取函数。
用 mysqli_fetch_all() 一次性取完所有行
这是最直接的方式,适合结果集不大、内存可控的场景。它返回二维数组,默认是数字索引,加 MYSQLI_ASSOC 可转为关联键名:
$result = mysqli_query($conn, "SELECT id, name FROM users WHERE status = 1"); $rows = mysqli_fetch_all($result, MYSQLI_ASSOC); // 得到 [ ['id'=>1,'name'=>'a'], ['id'=>2,'name'=>'b'] ]
- 不传第二个参数时返回数字索引,容易写错字段位置
- 如果 SQL 没有结果,
mysqli_fetch_all()返回空数组,不是null,可直接foreach - 注意:该函数要求 MySQLi 扩展开启,且 PHP >= 5.3.0
PDO::fetchAll() 更灵活但默认不带键名
PDO 默认返回数字索引数组,想按字段名访问必须显式指定 PDO::FETCH_ASSOC:
$stmt = $pdo->query("SELECT id, email FROM admins");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // 否则你拿到的是 [ [0=>1,1=>'x@y.z'], ... ]-
PDO::FETCH_BOTH会同时包含数字和字符串键,浪费内存,一般不用 - 如果用了预处理(
prepare/execute),记得检查$stmt->execute()是否成功再调fetchAll() - 大结果集慎用——
fetchAll()把全部数据加载进内存,可能触发memory_limit错误
大数据量时用 while + fetch() 流式读取
当查几万行甚至更多,别一股脑全 load 进来。逐行处理更安全:
立即学习“PHP免费学习笔记(深入)”;
$result = mysqli_query($conn, "SELECT * FROM logs WHERE created_at > '2024-01-01'");
while ($row = mysqli_fetch_assoc($result)) {
process_log($row); // 自定义处理逻辑
}- MySQLi 用
mysqli_fetch_assoc(),PDO 用$stmt->fetch(PDO::FETCH_ASSOC) - 此时
$result是资源句柄(MySQLi)或 PDOStatement 对象(PDO),不能重复遍历 - 如果中间出错或要提前退出,记得
mysqli_free_result($result)或让对象自动销毁
查不到数据时的常见假阳性判断
很多人写 if ($rows) 判断是否有结果,但空数组在 PHP 中是 true,而 mysqli_query() 失败才返回 false:
$result = mysqli_query($conn, "SELECT * FROM table WHERE 0");
if ($result === false) { /* SQL 错了 */ }
else if (mysqli_num_rows($result) === 0) { /* 有查询,但没数据 */ }
else { /* 正常有数据 */ }-
mysqli_num_rows()和$stmt->rowCount()才是判断“查到几条”的正确方式 -
mysqli_fetch_all()返回空数组 ≠ 查询失败,只是没匹配行 - 用 PDO 时,
$stmt->execute()返回true/false表示执行是否成功,不是结果有无
真正要注意的,是结果集大小和内存边界——查 100 条用 fetch_all 没问题,查 10 万条还这么干,脚本就等着被 Killed 或超时了。











