主要是MySQLi和PDO的一些学习,代码是面向对象的风格,与面向过程的思路大同,但写法小异
实例化MySQLi类:
$db = new mysqli(host,user,pass,dbname);
比如下例子中,我们连接本地数据库(localhost),用户名是root,密码是123123123,选择的数据库是dmind
$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']}";
}
$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
//设置编码方式
$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
";
}
}
$result->free();
}
if ($db->more_results()){
//检查批量查询中是否还有查询结果
printf("----------------
");
}
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
$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 是一个「数据库访问抽象层」,作用是统一各种数据库的访问接口
要建立 PHP 程序与数据库的连接,必须先实例化 PDO 的构造函数
PDO::__construct ( string $dsn , string $username = ? , string $password = ? , array $driver_options = ? )
dsn:数据源名称,包括主机名端口号和数据库名称。通常,一个 DSN 由 PDO 驱动名、紧随其后的冒号以及具体 PDO 驱动的连接语法组成。
username:连接数据库的用户名。
password:连接数据库的密码。
driver_options:连接数据库的其他选项。
具体的连接案例:
$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
案例:
$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 "
-------------------------
FETCH_ASSOC:
";
print_r($res);
$res = $sth->fetch(PDO::FETCH_BOTH);
echo "
-------------------------
FETCH_BOTH:
";
print_r($res);
$res = $sth->fetch(PDO::FETCH_LAZY);
echo "
-------------------------
FETCH_LAZY:
";
print_r($res);
$res = $sth->fetch(PDO::FETCH_OBJ);
echo "
-------------------------
FETCH_OBJ:
";
print_r($res);
?>
fetchall()
获取结果集中所有行的数据
prepare() 预处理,execute() 执行一条预处理语句
$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 '';
for ($i=0;$i<count($row);$i++){
echo '';
echo ''.$row[$i]['id'].' '.$row[$i]['pass'].' '.$row[$i]['username'].' ';
}
echo '
';
echo '共有'
.$sth->rowCount().'条记录';
}
catch(Exception $e){
echo "Failed!".$e->getMessage();
}
?>
exec()
】exec()
返回执行 SQL 语句后受影响的行数,通常用于 INSERT、DELETE 和 UPDATE 语句中
int PDO::exec(string statement)
$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 '';
echo '"id" "pass" "username" ';
for ($i=0;$i<count($row);$i++){
echo '';
echo ''.$row[$i]['id'].' '.$row[$i]['pass'].' '.$row[$i]['username'].' ';
}
echo '
';
echo '共有'
.$sth->rowCount().'条记录,此次执行影响了'.($count?$count:0)."行";
}
catch(Exception $e){
echo "Failed!".$e->getMessage();
}
返回执行查询后的结果集
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 '';
echo '"id" "pass" "username" ';
foreach ($sth as $row){
echo '';
echo ''.$row['id'].' '.$row['pass'].' '.$row['username'].' ';
}
echo '
';
echo '共有'
.$sth->rowCount().'条记录,此次执行影响了'.($count?$count:0)."行";
}
catch(Exception $e){
echo "Failed!".$e->getMessage();
}
?>