PHP基础学习(三)

前言:

主要是MySQLi和PDO的一些学习,代码是面向对象的风格,与面向过程的思路大同,但写法小异

MySQLi 对象接口

实例化MySQLi类:

$db = new mysqli(host,user,pass,dbname);

比如下例子中,我们连接本地数据库(localhost),用户名是root,密码是123123123,选择的数据库是dmind

<?php
$db = new mysqli("localhost","root","123123123","dmind");//将 MySQLi 类实例化到变量 $db 中
$sql = "INSERT INTO users (id,pass,username) VALUES(2,666,'Lisa')";

if ($db->query($sql)){
	echo "save successfully";
}
else{
	echo "Wrong!";
}
$db->close();//调用类的 close()方法,在内存中清理和销毁类
?>

对于:增、删、改、查之类的其它语句,在 MySQLi 中,我们统一只使用 query() 方法就可以了

单语句执行:

返回查询结果:fetch_row()fetch_assoc()

$mysqli_result->fetch_row();//返回查询结果的索引部分,返回一行
$mysqli_result->fetch_assoc();//返回查询结果的关联部分,返回一行

释放结果集所占用的内存:

mysqli_result::free
mysqli_result::close
$db = new mysqli("localhost","root","123123123","dmind");//将 MySQLi 类实例化到变量 $db 中

if (mysqli_connect_errno()){
	printf("Connect Falied:%s\n",mysqli_connect_error());
	exit();
}

$sql = "SELECT * FROM users;";


$result = $db->query($sql);//将返回的信息存储到变量 $result
while ($row = $result->fetch_assoc()){
	echo "{$row['id']} : {$row['pass']} : {$row['username']}</br>";
}
$result->free();//释放内存资源
$db->close();
?>
多语句执行:

将mysqli_query()查询的结果集存储到变量中,一般用于多语句执行:

mysqli::store_result ( int $option = ? ) : mysqli_result

检查批量查询中是否还有查询结果:

mysqli::more_results ( ) : bool

准备multi_query的下一个结果集,一般放在more_results()后使用

mysqli::next_result ( ) : bool
<?php
//设置编码方式
$db->query('set names utf8');

$sql = "SELECT * FROM users;";
$sql .= "select @@basedir;";

if ($db->multi_query($sql)){
	do {
		if ($result = $db->store_result()){	//取出一个结果集
			while ($row = $result->fetch_assoc()){//从结果集中取出一行,用来返回查询结果的索引或者关联部分
				//print_r($row);
				foreach ($row as $k=>$v){	//将数组循环输出
					echo "$k : $v<br>";
				}				
			}
			$result->free();
		}
		if ($db->more_results()){//检查批量查询中是否还有查询结果
			printf("----------------<br>");
		}
		else{		
			break; //没有则退出
		}
	}
	while($db->next_result());//准备下一个结果集。
}

$db->close();

在这里插入图片描述

事务

MYSQL事务处理让所有sql语句执行成功后才去处理,如果有一条没有成功或者报错就会回滚事务,防止敏感操作处理失败。

MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其它类型是不支持的!

自动提交事务:每执行一条sql语句,就同步到数据库中,默认情况下都是开启自动提交事务的。可以通过$db->autocommit(FALSE);关闭

我们需要用到MySQLi_Driver类将对象中的报错属性为抛出异常

// 使用异常处理错误情况
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT;
 commit()  提交一个事务
 rollBack() 回滚一个事务。回滚由方法commit()发起的当前事务

事务处理的案例:

$db = new mysqli("localhost","root","123123123","dmind");//将 MySQLi 类实例化到变量 $db 中
$db->autocommit(FALSE);

$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT;

try{
	$db->begin_transaction();//开启事务
	$sql1 = "INSERT INTO users (id,pass,username) VALUES(70,666,'Lisa')";
	$sql2 = "select * from aaa";	//不存在的表,执行不会成功
	$db->query($sql1);	
	$db->query($sql2);
	$db->commit();	//提交事务
	echo "successfully";
}
catch(Exception  $e){
	$db->rollback();	//回滚事务
	var_dump($e->getMessage());
}
$db->close();

当然还可以用affected_rows来判断,但是感觉不如异常抛出好:

$db = new mysqli("localhost","root","123123123","dmind");//将 MySQLi 类实例化到变量 $db 中

$db->autocommit(FALSE);//关闭自动提交事务的功能

$db->begin_transaction();//开启事务
$sql1 = "INSERT INTO users (id,pass,username) VALUES(70,666,'Lisa')";
$sql2 = "select * from aaa";	//不存在的表,执行不会成功
$db->query($sql1);
$res1_rows = $db->affected_rows;	//affected_rows:受影响的行数
$db->query($sql2);
$res2_rows = $db->affected_rows;

if($res1_rows >0 && $res2_rows >0){ 
	$db->commit();	//都没问题就提交事务
	echo "successfully";
}
else {
	$db->rollback();	//有问题,回滚事务
	echo "Failed";
}
预处理:

官方文档:https://www.php.net/manual/zh/class.mysqli-stmt.php

MySQLi的占位符只有:?

bind_param 参数绑定

public mysqli_stmt::bind_param ( string $types , mixed &$var , mixed &...$vars ) : bool
其中$types有四种:s(stirng)i(int)d(double)b(blog)
$types可以连着使用,如:"ssd" 表示前两位都是字符型、第三位是数字型

bind_result 绑定结果集

public mysqli_stmt::bind_result ( mixed &$var , mixed &...$vars ) : bool
<?php
$db = new mysqli("localhost","root","123123123","dmind");//将 MySQLi 类实例化到变量 $db 中
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);//开启报错
$id=2;
$name='Lisa';
$stmt = $db->prepare("SELECT * FROM users WHERE username=? and id=?"); //用?占位
$stmt->bind_param("sd",$name,$id);	//参数绑定
$stmt->bind_result($id,$pass,$name);//结果绑定
$stmt->execute();	//用execute()执行预处理语句

while ($stmt->fetch()){ //用fetch()用于获取结果
	echo "$id---$pass--$name";
}
$stmt->close();
$db->close();
?>

PDO

PDO 是一个「数据库访问抽象层」,作用是统一各种数据库的访问接口

实例化(建立连接)

要建立 PHP 程序与数据库的连接,必须先实例化 PDO 的构造函数

PDO::__construct ( string $dsn , string $username = ? , string $password = ? , array $driver_options = ? )

dsn:数据源名称,包括主机名端口号和数据库名称。通常,一个 DSNPDO 驱动名、紧随其后的冒号以及具体 PDO 驱动的连接语法组成。

username:连接数据库的用户名。

password:连接数据库的密码。

driver_options:连接数据库的其他选项。

具体的连接案例:

<?php
$dsn = 'mysql:dbname=dmind;host=127.0.0.1';
$user = 'root';
$password = '123123123';
try{
	$dbn = new PDO($dsn,$user,$password);	
	echo "successfully!";
}
catch(Exception $e){
	echo "Failed!".$e->getMessage();
}
?>
获取单条数据

fetch() 获取结果集中的下一行数据

PDOStatement::fetch ( int $fetch_style = ? , int $cursor_orientation = PDO::FETCH_ORI_NEXT , int $cursor_offset = 0 ) : mixed

$fetch_style主要有:

关联数组形式:
PDO::FETCH_ASSOC

数字索引数组形式
PDO::FETCH NUM

两者数组形式都有,这是默认值
PDO::FETCH BOTH

按照对象的形式,类似于以前的 mysql_fetch_object()
PDO::FETCH_OBJ

以布尔值的形式返回结果,同时将获取的列值赋给 bindParam()方法中指定的变量
PDO::FETCH_BOUND

以关联数组、数字索引数组和对象 3 种形式返回结果
PDO::FETCH_LAZY

案例:

<?php
$dsn = 'mysql:dbname=dmind;host=127.0.0.1';
$user = 'root';
$password = '123123123';
try{
	$dbn = new PDO($dsn,$user,$password);	
	echo "successfully!";
}
catch(Exception $e){
	echo "Failed!".$e->getMessage();
}

$sth = $dbn->prepare('SELECT * FROM users');
$sth->execute();

$res = $sth->fetch(PDO::FETCH_ASSOC);
echo "<br>-------------------------<br>FETCH_ASSOC:<br>";
print_r($res);
$res = $sth->fetch(PDO::FETCH_BOTH);
echo "<br>-------------------------<br>FETCH_BOTH:<br>";
print_r($res);
$res = $sth->fetch(PDO::FETCH_LAZY);
echo "<br>-------------------------<br>FETCH_LAZY:<br>";
print_r($res);
$res = $sth->fetch(PDO::FETCH_OBJ);
echo "<br>-------------------------<br>FETCH_OBJ:<br>";
print_r($res);
?>

在这里插入图片描述

获取多条数据

fetchall() 获取结果集中所有行的数据
prepare() 预处理,execute() 执行一条预处理语句

<?php
$dsn = 'mysql:dbname=dmind;host=127.0.0.1';
$user = 'root';
$password = '123123123';
try{
	$dbn = new PDO($dsn,$user,$password);	
	$sth = $dbn->prepare('SELECT * FROM users');
	$sth->execute();
	$row = $sth->fetchAll(PDO::FETCH_ASSOC);
	//print_r($row);
	echo '<table border="1" celllpadding="5" cellspacing="0" width="70%" align="center">';
	for ($i=0;$i<count($row);$i++){
		echo '<tr align="center">';
		echo '<td>'.$row[$i]['id'].'</td><td>'.$row[$i]['pass'].'</td><td>'.$row[$i]['username'].'</td>';
	}
	echo '</table>';
	echo '<h3 align="center">共有'.$sth->rowCount().'条记录';
}
catch(Exception $e){
	echo "Failed!".$e->getMessage();
}
?>

在这里插入图片描述

增删改【exec()

exec()返回执行 SQL 语句后受影响的行数,通常用于 INSERT、DELETE 和 UPDATE 语句中

int PDO::exec(string statement)
<?php
$dsn = 'mysql:dbname=dmind;host=127.0.0.1';
$user = 'root';
$password = '123123123';
try{
	$dbn = new PDO($dsn,$user,$password);	
	
	$count=$dbn->exec('INSERT users(id,pass,username) VALUES("6","LaoLi","3344")');
	
	$sth = $dbn->prepare('SELECT * FROM users');
	$sth->execute();
	$row = $sth->fetchAll(PDO::FETCH_ASSOC);
	//print_r($row);
	echo '<table border="1" celllpadding="5" cellspacing="0" width="50%" align="center">';
	echo '<tr><td>"id"</td><td>"pass"</td><td>"username"</td></tr>';
	for ($i=0;$i<count($row);$i++){
		echo '<tr align="center">';
		echo '<td>'.$row[$i]['id'].'</td><td>'.$row[$i]['pass'].'</td><td>'.$row[$i]['username'].'</td>';
	}
	echo '</table>';
	echo '<h3 align="center">共有'.$sth->rowCount().'条记录,此次执行影响了'.($count?$count:0)."行";
}
catch(Exception $e){
	echo "Failed!".$e->getMessage();
}

在这里插入图片描述

query()

返回执行查询后的结果集

PDOStatement PDO::query(string statement)

query() 对比execute() 大同小异,但可以直接操作它的结果集进行遍历,而不用fetch()或者fetchall()

$dsn = 'mysql:dbname=dmind;host=127.0.0.1';
$user = 'root';
$password = '123123123';
try{
	$dbn = new PDO($dsn,$user,$password);	
	
	$count=$dbn->exec('INSERT users(id,pass,username) VALUES("6","LaoLi","3344")');
	
	$sth = $dbn->query('SELECT * FROM users');
	
	echo '<table border="1" celllpadding="5" cellspacing="0" width="50%" align="center">';
	echo '<tr><td>"id"</td><td>"pass"</td><td>"username"</td></tr>';
	foreach ($sth as $row){
		echo '<tr align="center">';
		echo '<td>'.$row['id'].'</td><td>'.$row['pass'].'</td><td>'.$row['username'].'</td>';
	}
	echo '</table>';
	echo '<h3 align="center">共有'.$sth->rowCount().'条记录,此次执行影响了'.($count?$count:0)."行";
}
catch(Exception $e){
	echo "Failed!".$e->getMessage();
}
?>
相关推荐
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页