mysqli_fetch_array()每次只取一行需循环使用,mysqli_fetch_all()一次性返回全部结果的二维数组;前者指针移动后不重置则后续为null,后者适合中小数据量场景但大数据易爆内存。

mysqli_fetch_array() 和 mysqli_fetch_all() 的区别在哪
直接用 mysqli_fetch_array() 只能取一行,循环调用才能拿到全部;而 mysqli_fetch_all() 一步到位,返回整个结果集的二维数组。别误以为前者能“自动转全量”,这是新手最常卡住的地方。
常见错误现象:var_dump($row) 只显示第一行,后面就 null —— 因为指针已移到末尾,没重置也没循环。
-
mysqli_fetch_array($result, MYSQLI_ASSOC)返回关联数组(键是字段名) -
mysqli_fetch_array($result, MYSQLI_NUM)返回数字索引数组 -
mysqli_fetch_array($result, MYSQLI_BOTH)同时含两种键(默认行为,但浪费内存) -
mysqli_fetch_all($result, MYSQLI_ASSOC)是更干净的选择,尤其做 JSON 输出或 foreach 遍历时
PDO::FETCH_ASSOC 和 fetchAll() 怎么配对用
PDO 更推荐统一用 PDO::FETCH_ASSOC,避免数字键和关联键混杂带来的维护麻烦。直接在 fetchAll() 里指定模式,比在循环里反复调 fetch() 更简洁、不易漏处理。
使用场景:API 接口返回数据、模板渲染前组装结构、批量写入前校验格式。
- 错误写法:
$stmt->fetch()单次调用后不循环,只拿到首行 - 正确写法:
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC) - 如果字段名含大小写混合(如
userEmail),MySQL 默认返回小写,PDO 不会自动驼峰转换——得自己映射 - 注意
PDO::ATTR_CASE => PDO::CASE_LOWER这类配置会影响键名,调试时可先var_dump(array_keys($rows[0]))确认
查出来是对象,怎么快速变数组
用 mysqli_fetch_object() 或 PDO::FETCH_OBJ 得到的是 stdClass 实例,不能直接当数组用。强行 foreach($obj as $k => $v) 虽然能遍历,但 isset($obj['id']) 会报错。
安全转数组的方法只有两个:
-
(array) $obj—— 最快,但只转一级,嵌套对象不会递归 -
json_decode(json_encode($obj), true)—— 兼容嵌套,但有性能开销,且会丢掉 null 值和某些资源类型 - 别用
get_object_vars(),它只返回 public 属性,对 PDO 返回的匿名对象无效
大数据量下 fetch_all() 会爆内存吗
会。比如查 10 万行,每行 1KB,光数组就占 100MB 内存。这时候必须放弃“全量转数组”思路,改用流式处理。
性能影响明显:PHP 默认内存限制 128MB,fetch_all() 一次性加载所有数据,容易触发 Fatal error: Allowed memory size exhausted。
- 替代方案:用
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { ... }边取边处理 - 如果非得数组,考虑分页 +
limit+offset,或用游标(cursor)方式迭代 - 注意 MySQL 的
mysqlnd驱动支持PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,可减少内存占用,但要求后续不能执行其他查询
真正要小心的不是语法怎么写,而是没意识到“结果集转数组”这个动作本身,在大数据场景下就是个隐性陷阱。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











