在之前的文章中,我们就已经接触过 MYSQLI_result 相关的内容。它的作用其实就是一个查询的结果集。不过在 PDO 中,一般直接通过 query() 或者 PDOStatement 对象进行查询之后就会返回结果。但在 MySQLi 中,会把查询到的结果也放入一个对象中,这就是 MySQLI_result 对象。

MySQLI_result 对象属性

首先,我们要通过一段查询来获得一个 MySQLI_result 对象。

  1. $stmt = $mysqli->prepare("select * from zyblog_test_user where username = 'kkk'");
  2. $stmt->execute(); // 执行语句
  3. $result = $stmt->get_result();
  4. var_dump($result);
  5. // object(mysqli_result)#3 (5) {
  6. // ["current_field"]=>
  7. // int(0)
  8. // ["field_count"]=>
  9. // int(4)
  10. // ["lengths"]=>
  11. // NULL
  12. // ["num_rows"]=>
  13. // int(7)
  14. // ["type"]=>
  15. // int(0)
  16. // }

如果使用的 MYSQLI_STMT 的话,直接在 execute() 方法执行查询语句之后,就可以通过 get_result() 方法获得一个 MySQLI_result 对象。

在这个对象中,我们可以看到有 current_field 当前字段 、 field_count 字段数量 、 lengths 字段长度 、 num_rows 行数 、 type 这些属性内容。不少同学会发现,current_field 和 lengths 好像并没有什么实际的内容,其实这两个属性是需要在特定操作下才会显示内容的,比如 lengths 是要在 fetch() 结果集之后才会有信息的。

  1. $result->fetch_array();
  2. var_dump($result);
  3. // ……
  4. // ……
  5. // ["lengths"]=>
  6. // array(4) {
  7. // [0]=>
  8. // int(0)
  9. // [1]=>
  10. // int(3)
  11. // [2]=>
  12. // int(3)
  13. // [3]=>
  14. // int(2)
  15. // }
  16. // ……
  17. // ……

而 current_field 属性的内容我们将在下面遍历查看字段信息的时候再展示它的内容。

查询结果集获取

MySQLI_result 对象的可见属性中,我们只能看到上面的那些信息。对于我们的业务开发来说其实用处不大,除了 num_rows 可以用来根据行数判断查询是否有结果之外,更重要的是我们要获取到结果集中的数据信息,这时就需要使用其它的函数来进行数据的获取了。

获取全部结果集

  1. var_dump($result->fetch_all());
  2. // array(7) {
  3. // [0]=>
  4. // array(4) {
  5. // [0]=>
  6. // int(42)
  7. // [1]=>
  8. // string(3) "kkk"
  9. // [2]=>
  10. // string(3) "666"
  11. // [3]=>
  12. // string(2) "k6"
  13. // }
  14. // ……
  15. // ……
  16. $result->data_seek(0);
  17. var_dump($result->fetch_all(MYSQLI_ASSOC));
  18. // array(7) {
  19. // [0]=>
  20. // array(4) {
  21. // ["id"]=>
  22. // int(42)
  23. // ["username"]=>
  24. // string(3) "kkk"
  25. // ["password"]=>
  26. // string(3) "666"
  27. // ["salt"]=>
  28. // string(2) "k6"
  29. // }
  30. // ……
  31. // ……

fetch_all() 方法就是用来获取全部的数据集内的数据,并以数组的形式返回,它可以指定返回的格式,默认情况下是 MYSQLI_NUM 这种数组下标的形式,和 PDO 类似,我们直接指定为 MySQLI_ASSOC 就可以返回键名形式的数据内容。

data_seek() 方法是移动结果集的下标。当我们获取或者使用后面要介绍的方法循环遍历完成一次结果集之后,再次遍历的话它的游标已经处于最后一位的,这样是无法获取数据的。在上面的代码中,我们就是将游标两次返回到 0 下标的位置,也就是最初始的位置,这样我们就可以重复地操作这一个结果集了。

获取普通结果集

如果要一行一行数据的获取,我们就可以使用各种形式的结果集数据获取方式。

  1. var_dump($result->fetch_array());
  2. // array(8) {
  3. // [0]=>
  4. // int(42)
  5. // ["id"]=>
  6. // int(42)
  7. // [1]=>
  8. // string(3) "kkk"
  9. // ["username"]=>
  10. // string(3) "kkk"
  11. // [2]=>
  12. // string(3) "666"
  13. // ["password"]=>
  14. // string(3) "666"
  15. // [3]=>
  16. // string(2) "k6"
  17. // ["salt"]=>
  18. // string(2) "k6"
  19. // }
  20. var_dump($result->fetch_array(MYSQLI_ASSOC));
  21. // array(4) {
  22. // ["id"]=>
  23. // int(43)
  24. // ["username"]=>
  25. // string(3) "kkk"
  26. // ["password"]=>
  27. // string(3) "666"
  28. // ["salt"]=>
  29. // string(2) "k6"
  30. // }

使用 fetch_array() 就是获取下一行的结果数据并以数组的形式返回,同样它也可以指定返回结果集的格式,和 fetch_all() 是类似的,只不过它是只获取下一行而不是全部的数据集,而且它的参数默认是返回的 MYSQLI_BOTH ,也就是数字下标和键名下标同时返回结果。

另外还有一个 fetch_assoc() 方法,直接就是返回 MYSQLI_ASSOC 格式的数据,这个方法不需要任何参数,它可以看成是 fetch_array(MYSQLI_ASSOC) 这种使用方式的一个封装。

  1. var_dump($result->fetch_assoc());
  2. // array(4) {
  3. // ["id"]=>
  4. // int(42)
  5. // ["username"]=>
  6. // string(3) "kkk"
  7. // ["password"]=>
  8. // string(3) "666"
  9. // ["salt"]=>
  10. // string(2) "k6"
  11. // }

而另外一个方法 fetch_row() ,则可以看成是和 fetch_array(MYSQLI_NUM) 相似的一个方法。它其实就是默认指定为 MySQLI_NUM 的结构返回方式。

  1. var_dump($result->fetch_row());
  2. // array(4) {
  3. // [0]=>
  4. // int(43)
  5. // [1]=>
  6. // string(3) "kkk"
  7. // [2]=>
  8. // string(3) "666"
  9. // [3]=>
  10. // string(2) "k6"
  11. // }

获取对象结果集

获取对象结果集其实和 PDO 中的相关功能也是类似的,它就是将结果直接放到一个类中,并实例化返回一个对象。

  1. ar_dump($result->fetch_object());
  2. // object(stdClass)#4 (4) {
  3. // ["id"]=>
  4. // int(42)
  5. // ["username"]=>
  6. // string(3) "kkk"
  7. // ["password"]=>
  8. // string(3) "666"
  9. // ["salt"]=>
  10. // string(2) "k6"
  11. // }

在这里我们没有指定类,所以它使用的是 stdClass 来返回的对象结构。我们也可以指定一个类,并且可以为这个类的构造函数传递参数,这一点也和 PDO 中的相关功能一样。

  1. class User
  2. {
  3. public function __construct()
  4. {
  5. print_r(func_get_args());
  6. }
  7. }
  8. var_dump($result->fetch_object('User', [1, 2, 3]));
  9. // Array
  10. // (
  11. // [0] => 1
  12. // [1] => 2
  13. // [2] => 3
  14. // )
  15. // object(User)#4 (4) {
  16. // ["id"]=>
  17. // int(42)
  18. // ["username"]=>
  19. // string(3) "kkk"
  20. // ["password"]=>
  21. // string(3) "666"
  22. // ["salt"]=>
  23. // string(2) "k6"
  24. // }

查询结果集字段信息获取

接下来我们再看看 MySQLI_result 对象中的字段相关信息的获取。我们可以直接获取到当前查询的结果集中的所有字段信息。

  1. while ($finfo = $result->fetch_field()) {
  2. var_dump($result->current_field);
  3. var_dump($finfo);
  4. }
  5. // int(1)
  6. // object(stdClass)#4 (13) {
  7. // ["name"]=>
  8. // string(2) "id"
  9. // ["orgname"]=>
  10. // string(2) "id"
  11. // ["table"]=>
  12. // string(16) "zyblog_test_user"
  13. // ["orgtable"]=>
  14. // string(16) "zyblog_test_user"
  15. // ["def"]=>
  16. // string(0) ""
  17. // ["db"]=>
  18. // string(9) "blog_test"
  19. // ["catalog"]=>
  20. // string(3) "def"
  21. // ["max_length"]=>
  22. // int(0)
  23. // ["length"]=>
  24. // int(11)
  25. // ["charsetnr"]=>
  26. // int(63)
  27. // ["flags"]=>
  28. // int(49667)
  29. // ["type"]=>
  30. // int(3)
  31. // ["decimals"]=>
  32. // int(0)
  33. // }
  34. // int(2)
  35. // object(stdClass)#5 (13) {
  36. // ["name"]=>
  37. // string(8) "username"
  38. // ["orgname"]=>
  39. // string(8) "username"
  40. // ……
  41. // ……

在这段代码中,我们查看了 MySQLI_result 对象的 current_field 属性信息,可以看出,它指出的就是当前位于哪个字段的下标。

字段的信息非常详细,这些属性的键名也很直观,这里就不作详细的说明了。

  1. $result->field_seek(1);
  2. while ($finfo = $result->fetch_field()) {
  3. var_dump($finfo);
  4. }
  5. // object(stdClass)#5 (13) {
  6. // ["name"]=>
  7. // string(8) "username"
  8. // ["orgname"]=>
  9. // string(8) "username"

我们同样也可以通过 field_seek() 方法来移动字段遍历的游标。在这里我们将游标移动到 1 ,就会从第二个 username 字段开始遍历。

  1. var_dump($result->fetch_fields());
  2. // array(4) {
  3. // [0]=>
  4. // object(stdClass)#5 (13) {
  5. // ["name"]=>
  6. // string(2) "id"
  7. // ["orgname"]=>
  8. // string(2) "id"
  9. // ["table"]=>
  10. // string(16) "zyblog_test_user"
  11. // ["orgtable"]=>
  12. // string(16) "zyblog_test_user"
  13. // ["def"]=>
  14. // string(0) ""
  15. // ["db"]=>
  16. // string(9) "blog_test"
  17. // ["catalog"]=>
  18. // string(3) "def"
  19. // ["max_length"]=>
  20. // int(0)
  21. // ["length"]=>
  22. // int(11)
  23. // ["charsetnr"]=>
  24. // int(63)
  25. // ["flags"]=>
  26. // int(49667)
  27. // ["type"]=>
  28. // int(3)
  29. // ["decimals"]=>
  30. // int(0)
  31. // }
  32. // [1]=>
  33. // object(stdClass)#4 (13) {
  34. // ["name"]=>
  35. // string(8) "username"
  36. var_dump($result->fetch_field_direct(2));
  37. // object(stdClass)#7 (13) {
  38. // ["name"]=>
  39. // string(8) "password"
  40. // ["orgname"]=>
  41. // string(8) "password"
  42. // ["table"]=>
  43. // string(16) "zyblog_test_user"
  44. // ["orgtable"]=>
  45. // string(16) "zyblog_test_user"
  46. // ["def"]=>
  47. // string(0) ""
  48. // ["db"]=>
  49. // string(9) "blog_test"
  50. // ["catalog"]=>
  51. // string(3) "def"
  52. // ["max_length"]=>
  53. // int(3)
  54. // ["length"]=>
  55. // int(765)
  56. // ["charsetnr"]=>
  57. // int(33)
  58. // ["flags"]=>
  59. // int(0)
  60. // ["type"]=>
  61. // int(253)
  62. // ["decimals"]=>
  63. // int(0)
  64. // }

fetch_fields() 方法和 fetch_all() 是类似的,它就是获取全部的字段信息。而 fetch_field_direct() 则是根据参数来获取指定下标的字段信息。

总结

至此,MySQLi 相关扩展的学习我们也就告一段落了,其它的一些类和函数比如 MySQLI_Driver 、 MySQLI_Exception 之类的内容大家可以自行查阅相关的文档,内容都不是很多。MySQLI_Driver 对象可以帮助我们指定当前驱动的报错形式,之前的文章中我们也已经接触过。

总体来说,整个 PHP 中和 MySQL 打交道的官方扩展我们就已经全部学习完了,PDO 和 MYSQLi 这两个扩展大家更主要的还是要掌握它们的区别和联系。在实际的业务开发中 PDO 还是会使用得更多,但 MySQLi 也绝不是能够完全忽略的,多多动手尝试学习吧。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/9.PHP中的MySQLi扩展学习(六)MySQLI_result对象操作.php

参考文档:

https://www.php.net/manual/zh/class.mysqli-result.php

PHP中的MySQLi扩展学习(六)MySQLI_result对象操作的更多相关文章

  1. PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作

    就像 PDO 中的 PDO_Statment 对象一样,MySQLI_STMT 对象也是一个预处理语句所形成的对象,专门用来操作 MySQLi 所生成的预处理语句的.其实操作方式之类也都比较相似,不外 ...

  2. PHP中的MySQLi扩展学习(四)mysqli的事务与预处理语句

    对于 MySQLi 来说,事务和预处理语句当然是它之所以能够淘汰 MySQL(原始) 扩展的资本.我们之前也已经学习过了 PDO 中关于事务和预处理语句相关的内容.所以在这里,我们就不再多讲理论方面的 ...

  3. PHP中的MySQLi扩展学习(三)mysqli的基本操作

    我们继续 MySQLi 扩展的学习,上篇文章中提到过,MySQLi 的扩展相对于 PDO 来说功能更加的丰富,所以我们依然还会在学习过程中穿插各种 MySQLi 中好玩的方法函数.不过,今天的主角是 ...

  4. PHP中的MySQLi扩展学习(二)mysqli类的一些少见的属性方法

    虽说是少见的一些属性方法,但是可能还是有不少同学在日常的开发中使用过,这里只是学习了可能相对来说我们用得比较少的一些 mysqli 的属性或方法.就当是扩展一下自己的知识体系. 切换用户 首先就是切换 ...

  5. PHP中的MySQLi扩展学习(一)MySQLi介绍

    关于 PDO 的学习我们告一段落,从这篇文章开始,我们继续学习另外一个 MySQL 扩展,也就是除了 PDO 之外的最核心的 MySQLi 扩展.可以说它的祖先,也就是 MySQL(原始) 扩展是我们 ...

  6. C#多线程学习(六) 互斥对象

    如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...

  7. Scala学习(六)---Scala对象

    Scala中的对象 摘要: 在本篇中,你将会学到何时使用Scala的object语法结构.在你需要某个类的单个实例时,或者想为其他值或函数找一个可以挂靠的地方时,你就会用到它.本篇的要点包括: 1. ...

  8. 解决phpMyAdmin中缺少mysqli扩展的错误

  9. phpmyadmin中缺少mysqli扩展 的结解办法

    修改 ;extension=php_mysqli.dll  去掉前面的 ;     以及 调整 php文件夹的目录位置.     这个办法是不是好使,我不确定.这个方法只适合 用win系统 这个,貌似 ...

随机推荐

  1. Java程序员的推荐阅读书籍

    作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...

  2. VueApp监听手机物理返回键的事件

    代码 第一步创建js文件夹子 在main里面引用   JS文本内容如下 //监听手机物理返回键的事件 document.addEventListener('plusready', function() ...

  3. Layui-自定义函数及调用

    控件 表格 时间范围 页面展示 场景 页面中选择开始时间和结束时间表格变化 使用 html代码 <div> <form class="layui-form" ac ...

  4. 30 个极大提高开发效率超级实用的 VSCode 插件

    Visual Studio Code 的插件对于在提升编程效率和加快工作速度非常重要.这里有 30 个最受欢迎的 VSCode 插件,它们将使你成为更高效的搬砖摸鱼大师.这些插件主要适用于前端开发人员 ...

  5. Centos7上yum安装redis

    下载tar包 wget http://download.redis.io/releases/redis-6.0.5.tar.gz 解压tar包 tar -zxvf redis-6.0.5.tar.gz ...

  6. MySQL——分表,分库操作

    说明 大数据量并且访问频繁的表,将其分为若干个表.如果不分的话,进行一次查询就会将表锁住,导致不能进行其他操作,故分表.表分割垂直分割应用场景:热数据放一个表里,冷数据放一个表里.冷数据使用MyIsa ...

  7. WPF 中的 路由事件

    public class ReportTimeEventArgs:RoutedEventArgs { public ReportTimeEventArgs(RoutedEvent routedEven ...

  8. C++11 unique_ptr智能指针详解

    在<C++11 shared_ptr智能指针>的基础上,本节继续讲解 C++11 标准提供的另一种智能指针,即 unique_ptr 智能指针. 作为智能指针的一种,unique_ptr ...

  9. 【mysql】mysql简介及高手是如何练成的

    1.什么是mysql  MySQL 是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于Oracle 公司. Mysql 是开源的,可以定制的,采用了GPL 协议,你可以修改源码 ...

  10. Linux初探之如何查看帮助文档自学命令

    linux命令种类繁多,参数各异,要每个都记住除非是过目不忘的神人,否则你只能记住常用的那几个,等到 要用时还是得靠--help,man,info这些命令去读文档,可是这些文档看起来也不那么直观,所以 ...