mysqli扩展库增强

批量处理

  • 基本语法
$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'";

在这里插入图片描述

  • 但当我们在语句末尾加上某些条件,会发现问题的严重性。
$sql="select * from user1 where name='zhang' and password='aa' or 1=1";

在这里插入图片描述

  • 使用预处理将很好的解决该问题。
  • 另一种解决方案:改变验证逻辑。
$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>

在这里插入图片描述

©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页