$stmt=$mysqli->prepare("selectfromzyblog_test_userwhereusername='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 中的干系功能一样。
classUser{publicfunction__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://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