PHP中的MySQLi扩展学习(六)MySQLI_result对象操作
在之前的文章中,我们就已经接触过 MYSQLI_result 相关的内容。它的作用其实就是一个查询的结果集。不过在 PDO 中,一般直接通过 query() 或者 PDOStatement 对象进行查询之后就会返回结果。但在 MySQLi 中,会把查询到的结果也放入一个对象中,这就是 MySQLI_result 对象。
MySQLI_result 对象属性
首先,我们要通过一段查询来获得一个 MySQLI_result 对象。
$stmt = $mysqli->prepare("select * from zyblog_test_user where username = 'kkk'");
$stmt->execute(); // 执行语句
$result = $stmt->get_result();
var_dump($result);
// object(mysqli_result)#3 (5) {
// ["current_field"]=>
// int(0)
// ["field_count"]=>
// int(4)
// ["lengths"]=>
// NULL
// ["num_rows"]=>
// int(7)
// ["type"]=>
// int(0)
// }
如果使用的 MYSQLI_STMT 的话,直接在 execute() 方法执行查询语句之后,就可以通过 get_result() 方法获得一个 MySQLI_result 对象。
在这个对象中,我们可以看到有 current_field 当前字段 、 field_count 字段数量 、 lengths 字段长度 、 num_rows 行数 、 type 这些属性内容。不少同学会发现,current_field 和 lengths 好像并没有什么实际的内容,其实这两个属性是需要在特定操作下才会显示内容的,比如 lengths 是要在 fetch() 结果集之后才会有信息的。
$result->fetch_array();
var_dump($result);
// ……
// ……
// ["lengths"]=>
// array(4) {
// [0]=>
// int(0)
// [1]=>
// int(3)
// [2]=>
// int(3)
// [3]=>
// int(2)
// }
// ……
// ……
而 current_field 属性的内容我们将在下面遍历查看字段信息的时候再展示它的内容。
查询结果集获取
MySQLI_result 对象的可见属性中,我们只能看到上面的那些信息。对于我们的业务开发来说其实用处不大,除了 num_rows 可以用来根据行数判断查询是否有结果之外,更重要的是我们要获取到结果集中的数据信息,这时就需要使用其它的函数来进行数据的获取了。
获取全部结果集
var_dump($result->fetch_all());
// array(7) {
// [0]=>
// array(4) {
// [0]=>
// int(42)
// [1]=>
// string(3) "kkk"
// [2]=>
// string(3) "666"
// [3]=>
// string(2) "k6"
// }
// ……
// ……
$result->data_seek(0);
var_dump($result->fetch_all(MYSQLI_ASSOC));
// array(7) {
// [0]=>
// array(4) {
// ["id"]=>
// int(42)
// ["username"]=>
// string(3) "kkk"
// ["password"]=>
// string(3) "666"
// ["salt"]=>
// string(2) "k6"
// }
// ……
// ……
fetch_all() 方法就是用来获取全部的数据集内的数据,并以数组的形式返回,它可以指定返回的格式,默认情况下是 MYSQLI_NUM 这种数组下标的形式,和 PDO 类似,我们直接指定为 MySQLI_ASSOC 就可以返回键名形式的数据内容。
data_seek() 方法是移动结果集的下标。当我们获取或者使用后面要介绍的方法循环遍历完成一次结果集之后,再次遍历的话它的游标已经处于最后一位的,这样是无法获取数据的。在上面的代码中,我们就是将游标两次返回到 0 下标的位置,也就是最初始的位置,这样我们就可以重复地操作这一个结果集了。
获取普通结果集
如果要一行一行数据的获取,我们就可以使用各种形式的结果集数据获取方式。
var_dump($result->fetch_array());
// array(8) {
// [0]=>
// int(42)
// ["id"]=>
// int(42)
// [1]=>
// string(3) "kkk"
// ["username"]=>
// string(3) "kkk"
// [2]=>
// string(3) "666"
// ["password"]=>
// string(3) "666"
// [3]=>
// string(2) "k6"
// ["salt"]=>
// string(2) "k6"
// }
var_dump($result->fetch_array(MYSQLI_ASSOC));
// array(4) {
// ["id"]=>
// int(43)
// ["username"]=>
// string(3) "kkk"
// ["password"]=>
// string(3) "666"
// ["salt"]=>
// string(2) "k6"
// }
使用 fetch_array() 就是获取下一行的结果数据并以数组的形式返回,同样它也可以指定返回结果集的格式,和 fetch_all() 是类似的,只不过它是只获取下一行而不是全部的数据集,而且它的参数默认是返回的 MYSQLI_BOTH ,也就是数字下标和键名下标同时返回结果。
另外还有一个 fetch_assoc() 方法,直接就是返回 MYSQLI_ASSOC 格式的数据,这个方法不需要任何参数,它可以看成是 fetch_array(MYSQLI_ASSOC) 这种使用方式的一个封装。
var_dump($result->fetch_assoc());
// array(4) {
// ["id"]=>
// int(42)
// ["username"]=>
// string(3) "kkk"
// ["password"]=>
// string(3) "666"
// ["salt"]=>
// string(2) "k6"
// }
而另外一个方法 fetch_row() ,则可以看成是和 fetch_array(MYSQLI_NUM) 相似的一个方法。它其实就是默认指定为 MySQLI_NUM 的结构返回方式。
var_dump($result->fetch_row());
// array(4) {
// [0]=>
// int(43)
// [1]=>
// string(3) "kkk"
// [2]=>
// string(3) "666"
// [3]=>
// string(2) "k6"
// }
获取对象结果集
获取对象结果集其实和 PDO 中的相关功能也是类似的,它就是将结果直接放到一个类中,并实例化返回一个对象。
ar_dump($result->fetch_object());
// object(stdClass)#4 (4) {
// ["id"]=>
// int(42)
// ["username"]=>
// string(3) "kkk"
// ["password"]=>
// string(3) "666"
// ["salt"]=>
// string(2) "k6"
// }
在这里我们没有指定类,所以它使用的是 stdClass 来返回的对象结构。我们也可以指定一个类,并且可以为这个类的构造函数传递参数,这一点也和 PDO 中的相关功能一样。
class User
{
public function __construct()
{
print_r(func_get_args());
}
}
var_dump($result->fetch_object('User', [1, 2, 3]));
// Array
// (
// [0] => 1
// [1] => 2
// [2] => 3
// )
// object(User)#4 (4) {
// ["id"]=>
// int(42)
// ["username"]=>
// string(3) "kkk"
// ["password"]=>
// string(3) "666"
// ["salt"]=>
// string(2) "k6"
// }
查询结果集字段信息获取
接下来我们再看看 MySQLI_result 对象中的字段相关信息的获取。我们可以直接获取到当前查询的结果集中的所有字段信息。
while ($finfo = $result->fetch_field()) {
var_dump($result->current_field);
var_dump($finfo);
}
// int(1)
// object(stdClass)#4 (13) {
// ["name"]=>
// string(2) "id"
// ["orgname"]=>
// string(2) "id"
// ["table"]=>
// string(16) "zyblog_test_user"
// ["orgtable"]=>
// string(16) "zyblog_test_user"
// ["def"]=>
// string(0) ""
// ["db"]=>
// string(9) "blog_test"
// ["catalog"]=>
// string(3) "def"
// ["max_length"]=>
// int(0)
// ["length"]=>
// int(11)
// ["charsetnr"]=>
// int(63)
// ["flags"]=>
// int(49667)
// ["type"]=>
// int(3)
// ["decimals"]=>
// int(0)
// }
// int(2)
// object(stdClass)#5 (13) {
// ["name"]=>
// string(8) "username"
// ["orgname"]=>
// string(8) "username"
// ……
// ……
在这段代码中,我们查看了 MySQLI_result 对象的 current_field 属性信息,可以看出,它指出的就是当前位于哪个字段的下标。
字段的信息非常详细,这些属性的键名也很直观,这里就不作详细的说明了。
$result->field_seek(1);
while ($finfo = $result->fetch_field()) {
var_dump($finfo);
}
// object(stdClass)#5 (13) {
// ["name"]=>
// string(8) "username"
// ["orgname"]=>
// string(8) "username"
我们同样也可以通过 field_seek() 方法来移动字段遍历的游标。在这里我们将游标移动到 1 ,就会从第二个 username 字段开始遍历。
var_dump($result->fetch_fields());
// array(4) {
// [0]=>
// object(stdClass)#5 (13) {
// ["name"]=>
// string(2) "id"
// ["orgname"]=>
// string(2) "id"
// ["table"]=>
// string(16) "zyblog_test_user"
// ["orgtable"]=>
// string(16) "zyblog_test_user"
// ["def"]=>
// string(0) ""
// ["db"]=>
// string(9) "blog_test"
// ["catalog"]=>
// string(3) "def"
// ["max_length"]=>
// int(0)
// ["length"]=>
// int(11)
// ["charsetnr"]=>
// int(63)
// ["flags"]=>
// int(49667)
// ["type"]=>
// int(3)
// ["decimals"]=>
// int(0)
// }
// [1]=>
// object(stdClass)#4 (13) {
// ["name"]=>
// string(8) "username"
var_dump($result->fetch_field_direct(2));
// object(stdClass)#7 (13) {
// ["name"]=>
// string(8) "password"
// ["orgname"]=>
// string(8) "password"
// ["table"]=>
// string(16) "zyblog_test_user"
// ["orgtable"]=>
// string(16) "zyblog_test_user"
// ["def"]=>
// string(0) ""
// ["db"]=>
// string(9) "blog_test"
// ["catalog"]=>
// string(3) "def"
// ["max_length"]=>
// int(3)
// ["length"]=>
// int(765)
// ["charsetnr"]=>
// int(33)
// ["flags"]=>
// int(0)
// ["type"]=>
// int(253)
// ["decimals"]=>
// int(0)
// }
fetch_fields() 方法和 fetch_all() 是类似的,它就是获取全部的字段信息。而 fetch_field_direct() 则是根据参数来获取指定下标的字段信息。
总结
至此,MySQLi 相关扩展的学习我们也就告一段落了,其它的一些类和函数比如 MySQLI_Driver 、 MySQLI_Exception 之类的内容大家可以自行查阅相关的文档,内容都不是很多。MySQLI_Driver 对象可以帮助我们指定当前驱动的报错形式,之前的文章中我们也已经接触过。
总体来说,整个 PHP 中和 MySQL 打交道的官方扩展我们就已经全部学习完了,PDO 和 MYSQLi 这两个扩展大家更主要的还是要掌握它们的区别和联系。在实际的业务开发中 PDO 还是会使用得更多,但 MySQLi 也绝不是能够完全忽略的,多多动手尝试学习吧。
测试代码:
参考文档:
https://www.php.net/manual/zh/class.mysqli-result.php
PHP中的MySQLi扩展学习(六)MySQLI_result对象操作的更多相关文章
- PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作
就像 PDO 中的 PDO_Statment 对象一样,MySQLI_STMT 对象也是一个预处理语句所形成的对象,专门用来操作 MySQLi 所生成的预处理语句的.其实操作方式之类也都比较相似,不外 ...
- PHP中的MySQLi扩展学习(四)mysqli的事务与预处理语句
对于 MySQLi 来说,事务和预处理语句当然是它之所以能够淘汰 MySQL(原始) 扩展的资本.我们之前也已经学习过了 PDO 中关于事务和预处理语句相关的内容.所以在这里,我们就不再多讲理论方面的 ...
- PHP中的MySQLi扩展学习(三)mysqli的基本操作
我们继续 MySQLi 扩展的学习,上篇文章中提到过,MySQLi 的扩展相对于 PDO 来说功能更加的丰富,所以我们依然还会在学习过程中穿插各种 MySQLi 中好玩的方法函数.不过,今天的主角是 ...
- PHP中的MySQLi扩展学习(二)mysqli类的一些少见的属性方法
虽说是少见的一些属性方法,但是可能还是有不少同学在日常的开发中使用过,这里只是学习了可能相对来说我们用得比较少的一些 mysqli 的属性或方法.就当是扩展一下自己的知识体系. 切换用户 首先就是切换 ...
- PHP中的MySQLi扩展学习(一)MySQLi介绍
关于 PDO 的学习我们告一段落,从这篇文章开始,我们继续学习另外一个 MySQL 扩展,也就是除了 PDO 之外的最核心的 MySQLi 扩展.可以说它的祖先,也就是 MySQL(原始) 扩展是我们 ...
- C#多线程学习(六) 互斥对象
如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...
- Scala学习(六)---Scala对象
Scala中的对象 摘要: 在本篇中,你将会学到何时使用Scala的object语法结构.在你需要某个类的单个实例时,或者想为其他值或函数找一个可以挂靠的地方时,你就会用到它.本篇的要点包括: 1. ...
- 解决phpMyAdmin中缺少mysqli扩展的错误
- phpmyadmin中缺少mysqli扩展 的结解办法
修改 ;extension=php_mysqli.dll 去掉前面的 ; 以及 调整 php文件夹的目录位置. 这个办法是不是好使,我不确定.这个方法只适合 用win系统 这个,貌似 ...
随机推荐
- MySQL学习05(MySQL函数)
MySQL函数 常用函数 官方文档 : https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-ref.html 数据函数 SELECT ABS ...
- Shell-03-表达式和运算符
表达式和运算符 条件表达式语句 [ 1 -eq 1 ] [[ 1 -eq 1 ]] test 1 -eq 1 等同于 [ 1 -eq 1 ] [root@satest_192-168-3-121 sh ...
- 流动的观察者模式 | Flutter 设计模式
观察者模式,又称发布订阅模式,是一种行为设计模式--你可以定义一种订阅机制,可在对象事件发生时通知多个 观察 该对象的其他对象. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主 ...
- DVWA(三):SQL injection 全等级SQL注入
(本文不定期更新) 一.所需环境: 1.DVWA 2.web环境 phpstudy/wamp 3.burp suite 二.SQL注入产生的原因: 程序员在编写代码的时候,没有对用户输入数据的合法性进 ...
- websocket在慕课网中的应用
网上资料都是介绍概念,我们来看看实际网站怎么使用websocket的吧.限于自身水平解读并不深入,慕课网上的websocket某些字段不知何用. 是什么 是一种应用层协议,有html5而推出,是一种全 ...
- NOIP 模拟 $26\; \rm 神炎皇$
题解 \(by\;zj\varphi\) 一道 \(\varphi()\) 的题. 对于一个合法的数对,设它为 \((a*m,b*m)\) 则 \(((a+b)*m)|a*b*m^2\),所以 \(( ...
- NOIP 模拟 $12\; \text{简单的填数}$
题解 一个纯的贪心,被我搞成 \(dp\) 了,最后把错解删掉了,骗了 \(10pts\) 考虑如何贪心,设置一种二元组 \((x,l)\),\(x\) 表示当前值,\(l\) 表示当前最长连续长度. ...
- 教你使用ApiPost中的全局参数和目录参数
前面的示例中,我们都是在单一接口中填入不同的请求header.query.body参数.但在实际项目中,对于一批接口,往往具有相同的请求参数.此时,我们可以利用全局参数或者目录参数实现. 例如:常见的 ...
- python创建一个简单的服务
python -m http.server 8000 --bind 0.0.0.0 8000为端口 0.0.0.0允许远程访问
- TypeScript 入门指南 【大白话】
前言 聊聊为何要学习TypeScript? 从开发角度来讲, TypeScript 作为强类型语言,对属性有类型约束.在日常开发中少了减少了不必要的因参数类型造成的BUG,当你在使用同事封装好的函数时 ...