PHP mysqli_fetch_array() 函数(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

函数概述:数据库查询的桥梁

在 PHP 开发中,与数据库交互是核心功能之一。当我们通过 mysqli_query()mysqli_prepare() 执行 SQL 查询后,如何将返回的数据转化为可用的 PHP 变量?mysqli_fetch_array() 函数正是实现这一目标的关键工具。它如同一座桥梁,连接着数据库的“数据海洋”与 PHP 程序的“代码世界”,帮助开发者将抽象的查询结果转化为具体的数据结构。

通过这个函数,开发者可以逐行读取查询结果中的每一行数据,并选择性地以关联数组、数字索引数组或两者的混合形式存储数据。这种灵活性使其成为 PHP 中处理数据库查询结果的常用方法之一。


语法结构与参数解析

mysqli_fetch_array() 的基本语法如下:

mixed mysqli_fetch_array(
    mysqli_result $result,
    int $result_type = MYSQLI_BOTH
)

参数详解

  1. $result

    • 类型:mysqli_result 对象
    • 说明:必须是通过 mysqli_query()mysqli_store_result() 或其他数据库查询方法返回的结果集。
  2. $result_type(可选)

    • 类型:整型常量
    • 可选值:
      • MYSQLI_ASSOC:仅返回关联数组(键为列名)
      • MYSQLI_NUM:仅返回数字索引数组(键为 0 开始的整数)
      • MYSQLI_BOTH(默认):同时返回关联数组和数字索引数组

返回值类型

  • 成功时返回一个包含当前行数据的数组。
  • 当没有更多行时返回 false

关联数组与数字索引的比喻

想象一个图书馆的书架,每一层代表数据库查询结果中的一行数据:

  • 关联数组:如同书架上的标签,直接标注书籍的书名(列名)与内容(数据值)。
  • 数字索引:如同按顺序编号的书架层,通过位置(0、1、2…)定位书籍。
  • 两者的混合:就像书架同时拥有标签和编号,提供两种访问方式。

这种设计让开发者可以根据需求灵活选择数据访问方式,例如通过列名提高代码可读性,或通过索引优化性能。


基础使用场景与代码示例

场景 1:查询用户信息

// 连接数据库
$mysqli = new mysqli("localhost", "username", "password", "database");

// 检查连接
if ($mysqli->connect_error) {
    die("连接失败: " . $mysqli->connect_error);
}

// 执行查询
$query = "SELECT id, name, email FROM users WHERE active = 1";
$result = $mysqli->query($query);

// 使用默认的 MYSQLI_BOTH 模式
if ($result->num_rows > 0) {
    while ($row = mysqli_fetch_array($result)) {
        echo "ID: " . $row['id'] . "(索引0:" . $row[0] . ")<br>";
        echo "Name: " . $row['name'] . "(索引1:" . $row[1] . ")<br>";
        echo "Email: " . $row['email'] . "(索引2:" . $row[2] . ")<br><hr>";
    }
} else {
    echo "没有找到数据";
}

// 释放结果集并关闭连接
$result->free();
$mysqli->close();

输出示例

ID: 1(索引0:1)
Name: 张三(索引1:张三)
Email: zhangsan@example.com(索引2:zhangsan@example.com)

场景 2:仅使用关联数组

while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    echo "用户姓名:" . $row['name'];
}

此方式避免了数字索引的冗余,使代码更易维护。


进阶技巧:动态处理复杂结果集

技巧 1:混合索引的高效利用

当列名可能重复时(例如多表连接),数字索引可避免歧义:

// 假设查询为 SELECT users.id, orders.id AS order_id FROM users JOIN orders...
while ($row = mysqli_fetch_array($result)) {
    // 关联数组中 users.id 会被覆盖为 order_id
    // 数字索引保留原始顺序
    echo "用户ID:" . $row[0] . ",订单ID:" . $row[1];
}

技巧 2:结合 foreach 循环

// 将结果集转换为关联数组列表
$rows = [];
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $rows[] = $row;
}

// 后续遍历
foreach ($rows as $user) {
    echo $user['email'];
}

常见问题与解决方案

问题 1:为何返回 false

可能原因

  • 数据库查询未正确执行,$result 为空。
  • 已读取完所有行。

解决方案

if ($row = mysqli_fetch_array($result)) {
    // 正常处理
} else {
    // 检查查询是否成功
}

问题 2:如何避免内存溢出?

当结果集很大时,逐行处理比一次性加载更安全:

// 不建议的做法(可能占用大量内存)
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);

// 推荐做法
while ($row = mysqli_fetch_array($result)) {
    process_row($row); // 分批处理
}

与类似函数的对比

mysqli_fetch_assoc() vs mysqli_fetch_array()

函数名返回值类型性能对比(通常)
mysqli_fetch_array()混合数组略低(因双重索引)
mysqli_fetch_assoc()仅关联数组更快

当需要同时使用两种索引时,mysqli_fetch_array() 是唯一选择;若仅需关联数组,mysqli_fetch_assoc() 更高效。

mysqli_fetch_all() 的批量获取

mysqli_fetch_all() 可一次性获取所有行,但需注意内存消耗:

// 返回二维数组,类型由第二个参数指定
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);

实战案例:构建用户列表

需求:显示所有用户的姓名和注册时间

// 连接数据库(省略检查步骤)
$result = $mysqli->query("SELECT name, DATE_FORMAT(register_time, '%Y-%m-%d') AS formatted_time FROM users");

// 使用关联数组简化代码
echo "<table>";
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    echo "<tr>";
    echo "<td>" . htmlspecialchars($row['name']) . "</td>";
    echo "<td>" . $row['formatted_time'] . "</td>";
    echo "</tr>";
}
echo "</table>";

// 清理资源
$result->free();
$mysqli->close();

输出
| 姓名 | 注册时间 | |--------|------------| | 李四 | 2023-05-15 | | 王五 | 2023-05-16 |


性能优化建议

1. 避免不必要的双重索引

若仅需一种索引,显式指定类型:

// 仅使用数字索引
$row = mysqli_fetch_array($result, MYSQLI_NUM);

2. 限制查询字段

避免 SELECT *,仅获取所需列以减少传输和内存占用。

3. 使用预处理语句

结合 mysqli_prepare() 可提升安全性与性能:

$stmt = $mysqli->prepare("SELECT name FROM users WHERE id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();

结论:掌握数据访问的核心工具

PHP mysqli_fetch_array() 函数是连接数据库与 PHP 应用的关键桥梁。通过理解其语法、参数选择及实际应用场景,开发者可以高效、灵活地处理查询结果。无论是构建简单的数据展示页面,还是处理复杂的业务逻辑,合理使用该函数都能显著提升开发效率与代码质量。

在实际开发中,建议根据需求选择最合适的返回类型,结合预处理语句和资源管理方法,构建安全高效的数据库交互逻辑。掌握这一函数不仅是 PHP 开发的基础,更是迈向专业后端开发的重要一步。

最新发布