当前位置: 首页 > 后端技术 > PHP

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

时间:2023-03-29 19:23:49 PHP

MySQLI_STMT对象与PDO中的PDO_Statment对象一样,也是由preparedstatement构成的对象,专门用于操作MySQLi生成的preparedstatement。其实操作方法之类的也比较类似,无非是对SQL语句的一些操作,主要是根据绑定参数获取结果集。参数绑定和操作属性在之前的文章中,大家一定见过我们使用的bind_param()方法,它与PDO中的bindParam()方法有很大的不同。$stmt=$mysqli->prepare("insertintozyblog_test_user(username,password,salt)values(?,?,?)");$username='mysqli_username';$password='mysqli_password';$salt='mysqli_salt';$stmt->bind_param('sss',$username,$password,$salt);var_dump($stmt->insert_id);//int(232)var_dump($stmt->affected_rows);//int(1)$stmt->execute();$stmt->close();首先,如前所述,MySQLI_STMT中的绑定参数只能使用?问号占位符,然后在使用bind_param()时,使用Itis's'依次绑定参数,这个's'代表一个字符串。另外,'i'表示整数,'d'表示浮点数,'b'表示blob类型。另外,从上面的测试代码也可以看出,一个bind_param()方法可以绑定多个参数,'sss'是三个字符串,按顺序绑定。绑定好参数后,我们就可以通过execute()方法来执行语句了。和PDO一样,这个方法只返回成功或失败的信息,是一个布尔值。因此,我们需要通过MySQLI_STMT对象的insert_id获取新增数据的ID,或者通过affected_rows属性获取当前语句执行后受影响的行数,判断语句是否真正执行,是否符合我们的预期.最后,我们使用close()关闭当前的STMT对象。这样后面的操作就不能使用上面的$stmt对象了。接下来我们看看绑定错误的类型会怎样,以及MySQLI_STMT中关于错误信息的提示。$stmt=$mysqli->prepare("insertintozyblog_test_user(id,username,password,salt)values(?,?,?,?)");$id='s';$username='mysqli_username';$password='mysqli_password';$salt='mysqli_salt';$stmt->bind_param('isss',$username,$password,$salt);$stmt->execute();var_dump($stmt->errno);//int(2031)var_dump($stmt->error);//string(53)“没有为准备好的语句中的参数提供数据”var_dump($stmt->error_list);//array(1){//[0]=>//array(3){//["errno"]=>//int(2031)//["sqlstate"]=>//string(5)"HY000"//["error"]=>//string(53)"Nodataprovidedforparametersinpreparedstatement"//}//}$stmt->close();在代码中,我们添加了id参数的绑定,然后指定类型为'i',但是我们实际传递的变量是字符串类型,这会导致MySQLI_STMT产生错误。可以看出MySQLI_STMT的错误属性和信息与MySQLi对象基本一致。列绑定MySQLI_STMT除了请求查询语句参数的绑定外,还支持直接进行列绑定。就像PDO中的bindColumn()一样。$stmt=$mysqli->prepare("select*fromzyblog_test_userwhereusername=?");$username='kkk';$stmt->bind_param("s",$username);//绑定参数$stmt->bind_result($col1,$col2,$col3,$col4);$stmt->execute();//执行语句var_dump($stmt);//object(mysqli_stmt)#2(10){//["affected_rows"]=>//int(-1)//["insert_id"]=>//int(0)//["num_rows"]=>//int(0)//["param_count"]=>//int(1)//["field_count"]=>//int(4)//["errno"]=>//int(0)//["error"]=>//string(0)""//["error_list"]=>//array(0){//}//["sqlstate"]=>//string(5)"00000"//["id"]=>//int(3)//}while($stmt->fetch()){printf("%s%s%s%s",$col1,$col2,$col3,$col4);echoPHP_EOL;}//42kkk666k6//43kkk666k6//......var_dump($stmt->num_rows);//int(7)$stmt->close();当然,方法的名称还是有一些变化的。MySQLI_STMT中绑定列的方法名为bind_result()。虽然叫法不同,但功能其实大同小异。查询语句中有多个列名,必须绑定多个列名。在此表中,我们有四个字段,因此4个列变量通过引用传递绑定。在使用fetch()遍历查询结果对象时,就像是使用引用给这4个列变量赋值。在这段代码中,我们使用num_rows属性来获取查询结果中的行数,这仅适用于SELECT语句。上面介绍的affected_rows就是受影响的行数。这两个属性不是同一个概念!返回结果集执行fetch()方法返回一个boolean值,它的主要作用是将结果集绑定到指定的变量上,所以如果直接打印它的结果,是不会有任何有用信息的,我们必须通过以下方式获取数据绑定列变量。结果集的真实数据是通过另外一个方法获取一个MySQLI_result对象,然后像PDO的fetch()一样使用这个对象中的方法获取真实的结果集。$stmt=$mysqli->prepare("select*fromzyblog_test_userwhereusername='kkk'");$stmt->execute();//执行语句$result=$stmt->get_result();while($row=$result->fetch_assoc()){var_dump($row);}//array(4){//["id"]=>//int(42)//["username"]=>//string(3)"kkk"//["password"]=>//string(3)"666"//["salt"]=>//string(2)"k6"//}//...$stmt->close();在这里,我们通过get_result()方法得到一个结果集的一个MySQLI_result对象。然后通过对象的fetch_assoc(),得到键名形式的结果集数组。关于MySQLI_result对象的内容,我们会在下一篇文章中详细了解。保存结果集并移动游标最后是关于游标的移动。在上面的测试数据中,我们可以查询到7条数据,第一条数据的id为42,通过游标,我们可以直接在SQL语句结果集中不使用limit进行操作,得到需要的数据。$stmt=$mysqli->prepare("select*fromzyblog_test_userwhereusername='kkk'");$stmt->bind_result($col1,$col2,$col3,$col4);$stmt->execute();//执行语句$stmt->store_result();//一共7项,从第五项开始$stmt->data_seek(5);$stmt->fetch();printf("%s%s%s%s",$col1,$col2,$col3,$col4);//47kkk666k6echoPHP_EOL;$stmt->close();首先,我们需要使用store_result()方法将结果集保存在内存中,该方法与MySQLi中的store_result()方法相同。然后,通过data_seek()方法将游标移动5个位置,最后输出的结果就是后面两条数据的内容。是不是很棒的感觉!总结MySQLI_STMT对象的内容更多,但并不常用。从我们所解释的内容中,我们也可以看出它与PDO之间的许多区别。当然整体大方向基本一致,所以我们学习起来不会有太大的难度。掌握了理解之后,还需要更多的动手操作。基本功不可忽视!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/8.PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作.php参考文档:https://www.php.net/manual/zh/book.mysqli.php各媒体平台均可搜索【硬核项目经理】