批量处理
$sqls="sql语句1;sql语句2;sql语句3...";
$res=mysqli::multi_query($sqls);
- 如果$sqls是dml语句,则返回bool;如果$sqls是dql语句,则返回多个结果集;需要使用mysqli::store_result和mysqli::next_result配合取出各个结果集。
- 批量执行dml语句可以混合使用insert/update/delete,批量执行dql语句使用select。
- dml语句
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body>
<?php
$mysqli=new mysqli("localhost","root","********","test");
if($mysqli->connect_error){
die($mysqli->connect_error);
}
$mysqli->query("set names utf-8");
$sqls="insert into user1 values(4,'蔷薇',18,md5('23d'));";
$sqls.="insert into user1 values(5,'等待',17,md5('dffc'));";
$sqls.="update user1 set age=34 where id=2;";
$sqls.="delete from user1 where id=3;";
$res=$mysqli->multi_query($sqls);
if(!$res){
echo "执行失败".$mysqli->error;
}else{
echo "执行成功";
}
$mysqli->close();
?>
</body>
</html>
- dql语句
- $result=$mysqli->store_result();//获取当前结果集
- $mysqli->more_results()是否还有结果集
- $mysqli->next_result()指向下一个结果集
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body>
<?php
$mysqli=new mysqli("localhost","root","********","test");
if($mysqli->connect_error){
die($mysqli->connect_error);
}
$mysqli->query("set names utf-8");
$sqls="select * from user1;";
$sqls.="select * from words;";
if($res=$mysqli->multi_query($sqls)){
do{
//取出结果集
$result=$mysqli->store_result();
while($row=$result->fetch_row()){
foreach($row as $key=>$val){
echo $val." ";
}
echo "<br/>";
}
//mysqli_free_result($result);
$result->free();
if(!$mysqli->more_results()){
break;
}
echo "----结果----<br/>";
//到新的结果集
}while($mysqli->next_result());
}
$mysqli->close();
?>
</body>
</html>
事务管理
- 事务是由一组相关的dml语句组成,用于保证数据的一致性,所有语句要么全部成功,要么回滚。
- 语句
$mysqli->autocommit(false);//先将提交设置为false
$mysqli->rollback();//失败则回滚
$mysqli->commit();//成功则提交
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body>
<?php
$mysqli=new mysqli("localhost","root","********","test");
if($mysqli->connect_error){
die($mysqli->connect_error);
}
$mysqli->query("set names utf-8");
$mysqli->autocommit(false);
$sql1="update user1 set age=age-2 where id=2";
$sql2="update user1 set age=age+2 where id=4";
$res1=$mysqli->query($sql1);
$res2=$mysqli->query($sql2);
if(!$res1 || !$res2){
echo "执行失败".$mysqli->error;
$mysqli->rollback();
}else{
echo "执行成功";
$mysqli->commit();
}
$mysqli->close();
?>
</body>
</html>
预处理
- 假如我们要插入很多100个用户,以我们之前所学习的方法,一种是for循环语句,一种是多处理函数(mysqli->multi_query($sqls))。php里面操作mysql数据库的函数(扩展库),将sql语句传递给mysql数据库,由mysql数据库执行sql语句(编译sql语句→执行),以上两种方法会进行多次编译,效率低,因此引入预处理操作。
- 第一次发送时编译好,后续只需发送数据即可。
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body>
<?php
$mysqli=new mysqli("localhost","root","********","test");
if($mysqli->connect_error){
die($mysqli->connect_error);
}
$mysqli->query("set names utf-8");
$sql="insert into user1 values(?,?,?,?)";
//创建预处理对象
$mysqli_stmt=$mysqli->prepare($sql);
//参数设定
$id=6;
$name="王子";
$age=22;
$password="dsjk";
//绑定参数$mysqli_stmt->bind_param("各个参数的类型",$id,$name,$age,$password);
$mysqli_stmt->bind_param("isis",$id,$name,$age,$password);
//执行
$res=$mysqli_stmt->execute();
if(!$res){
die("操作失败".$mysqli_stmt->error);
}else{
echo "操作成功";
}
//参数设定
$id=7;
$name="公主";
$age=24;
$password="dsfk";
//绑定参数
$mysqli_stmt->bind_param("isis",$id,$name,$age,$password);
//执行
$res=$mysqli_stmt->execute();
if(!$res){
die("操作失败".$mysqli_stmt->error);
}else{
echo "操作成功";
}
$mysqli->close();
?>
</body>
</html>
- 查询
- $mysqli_stmt->bind_result($id,$name,$age);//绑定结果集
- $mysqli_stmt->fetch()//将结果集按行取出
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body>
<?php
$mysqli=new mysqli("localhost","root","********","test");
if($mysqli->connect_error){
die($mysqli->connect_error);
}
$mysqli->query("set names utf-8");
$sql="select id,name,age from user1 where age>?";
//创建预处理对象
$mysqli_stmt=$mysqli->prepare($sql);
//参数设定
$age=20;
//绑定参数
$mysqli_stmt->bind_param("i",$age);
//绑定结果集(引用)
$mysqli_stmt->bind_result($id,$name,$age);
//执行
$mysqli_stmt->execute();
//取出绑定值
while($mysqli_stmt->fetch()){
echo $id." ".$name." ".$age."<br/>";
}
$mysqli_stmt->free_result();
$mysqli_stmt->close();
$mysqli->close();
?>
</body>
</html>
- 预编译可以自动防止sql(结构化查询语句)注入攻击。
- 当我们编写以下查询语句时,想当然以为无差错:当密码输入错误不会出现相应信息。
$sql="select * from user1 where name='zhang' and password='aa'";
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a9c231bf57684f8e65dac60856cdd322.png)
- 但当我们在语句末尾加上某些条件,会发现问题的严重性。
$sql="select * from user1 where name='zhang' and password='aa' or 1=1";
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9b567ab831dce07479b8f8ce4f92699b.png)
- 使用预处理将很好的解决该问题。
- 另一种解决方案:改变验证逻辑。
$sql="select password from user1 where name='zhang';
if(数据库查询的密码==用户输入的密码){
//继续执行
}else{
//停止
}
其他函数
- $res->num_rows获取总行数
- $res->field_count获取总列数
- $field=$res->fetch_field();取列,返回的是对象;$field->name获取属性
- $row=$res->fetch_row()取行
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body>
<?php
function show($tableName){
$mysqli=new mysqli("localhost","root","********","test");
if($mysqli->connect_error){
die($mysqli->connect_error);
}
$mysqli->query("set names utf-8");
$sql="select * from $tableName";
$res=$mysqli->query($sql);
echo "总行数:".$res->num_rows." "."总列数:".$res->field_count;
echo "<table border='1'><tr>";
while($field=$res->fetch_field()){
echo "<th>{$field->name}</th>";
}
echo "</tr>";
while($row=$res->fetch_row()){
echo "<tr>";
foreach($row as $key=>$val){
echo "<th>$val</th>";
}
echo "</tr>";
}
echo "</table>";
$res->free();
$mysqli->close();
}
show("user1");
?>
</body>
</html>
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/823f36f45d135181176fb19eec6769ea.png)