赞
踩
PDO概述
连接数据库方式
mysql扩展 (这种方式php7已经淘汰)
mysqli扩展
PDO扩展
PDO介绍
PDO(PHP Data Object)扩展为PHP访问各种数据库提供了一个轻量级,一致性的接口
无论访问什么数据库,都可以通过一致性的接口去操作
开启PDO扩展
开启PDO连接MySQL扩展
extension=php_pdo_mysql.dll
PDO核心类
PDO 表示PHP和数据库之间的一个连接
PDOStatement
表示执行数据查询语句(select ,show)后的相关结果集
预处理对象
PDOException 表示PDO的异常
实例化PDO对象
语法
__construct($dsn,用户名,密码)
DSN
概念
DSN:data source name
数据源名称,包含的是连接数据库的信息
格式
$dsn=数据库类型:host=主机地址;port=端口号;dbname=数据库名称;charset=字符集
数据库类型
MySQL数据库 => mysql:
oracle数据库 =>oci:
SQL Server => sqlsrv:
实例化PDO
概念
实例化PDO的过程就是连接数据库的过程
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
var_dump($pdo);
?>
参数省略
参数省略
如果连接的是本地数据库,host可以省略
如果使用的是3306端口,port可以省略
charset也省略,如果省略,使用的是默认字符编码
dbname也可以省略,如果省略就没有选择数据库
host、port、dbname、charset不区分大小写,没有先后顺序
驱动名称不能省略,冒号不能省略(因为冒号是驱动名组成部分),数据库驱动只能小写
$dsn='mysql:';
$pdo=new PDO($dsn,'root','');
var_dump($pdo);
?>
使用PDO
执行数据操作语句
语法
$pdo->exec($sql)
执行数据增、删、改语句
执行成功返回受影响的记录数
如果SQL语句错误返回false
执行增加
$dsn='mysql:host=localhost;port=3306;dbname=sel;charset=utf8';
$pdo=new PDO($dsn,'root','');
if($pdo->exec("insert into news values (null,'基本知识','第6章',unix_timestamp())")){
echo '自动增长的编号是:'.$pdo->lastInsertId(),'
';
}
?>
执行删除
$dsn='mysql:host=localhost;port=3306;dbname=sel;charset=utf8';
$pdo=new PDO($dsn,'root','');
if($pdo->exec('delete from news where id=13')){
echo 'delete success ^_^';
}
?>
执行修改
$dsn='mysql:host=localhost;port=3306;dbname=sel;charset=utf8';
$pdo=new PDO($dsn,'root','');
if($pdo->exec("update news set title='准备知识' where id in (3,4)")){
echo 'update success ^_^';
}
?>
优化写法
$dsn= 'mysql:host=localhost;port=3306;dbname=sel;charset=utf8';
$pdo= new PDO($dsn,'root','');
$sql= "update news set title='基本知识' where id in (3,4)";
$rs= $pdo->exec($sql);
if($rs){
echo 'SQL语句执行成功
';
if(substr($sql, 0,6)=='insert')
echo '自动增长的编号是:'.$pdo->lastInsertId (),'
';
else
echo '受到影响的记录数是:'.$rs,'
';
}elseif($rs===0){
echo '数据没有变化
';
}elseif($rs===false){
echo 'SQL语句执行失败
';
echo '错误编号:'.$pdo->errorCode(),'
';
echo '错误信息:'.$pdo->errorInfo()[2];
}
?>
执行数据查询语句
语法
$pdo->query($sql)
返回的是PDOStatement对象
获取二维数组
$rs=$stmt->fetchAll(); 默认返回关联和索引数组
$rs=$stmt->fetchAll(PDO::FETCH_BOTH); 返回关联和索引数组
$rs=$stmt->fetchAll(PDO::FETCH_NUM); 返回索引数组
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC); 返回关联数组
$rs=$stmt->fetchAll(PDO::FETCH_OBJ); 返回对象数组
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetchAll();
var_dump($rs);
?>
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetchAll(PDO::FETCH_BOTH);
var_dump($rs);
?>
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetchAll(PDO::FETCH_NUM);
var_dump($rs);
?>
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($rs);
?>
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetchAll(PDO::FETCH_OBJ);
var_dump($rs);
?>
获取一维数组
$rs=$stmt->fetch(); 关联和索引数组
$rs=$stmt->fetch(PDO::FETCH_NUM); 索引数组
$row=$stmt->fetch(PDO::FETCH_ASSOC) 关联数组
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetch();
var_dump($rs);
?>
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
$rs=$stmt->fetch(PDO::FETCH_NUM);
var_dump($rs);
?>
# 通过while循环获取所有数据
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
$rs[]=$row;
}
var_dump($rs);
?>
匹配列
匹配当前行的第n列,列的编号从0开始,匹配完毕后指针下移一条
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
for($i=0; $icolumnCount(); $i++){
echo $stmt->fetchColumn($i).'
';
}
?>
总行数与总列数
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
echo '总行数:'.$stmt->rowCount(),'
';
echo '总列数:'.$stmt->columnCount();
?>
遍历PDOStatement对象
PDOStatement对象是有迭代器的
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$stmt=$pdo->query('select * from products');
foreach($stmt as $row){
echo $row['proname'],'-',$row['proprice'],'
';
}
?>
PDO操作事务
概念
事务:是一个整体,要么一起执行,要么一起回滚
事务的特性:原子性,一致性,隔离性,永久性
需要将多个SQL语句作为一个整体执行,就需要使用到事务
MySQL 事务语法
start transaction 开启事务
begin 开启事务
commit 提交事务
rollback 回滚事务
PDO 事务语法
$pdo->beginTransaction() 开启事务
$pdo->commit () 提交事务
$pdo->rollBack() 回滚事务
# 创建测试数据表
$dsn= 'mysql:host=localhost;port=3306;dbname=data;charset=utf8';
$pdo= new PDO($dsn,'root','');
$pdo->beginTransaction();
$flag0= $pdo->exec("delete from bank");
$flag1= $pdo->exec("drop table bank");
$flag2= $pdo->exec("create table bank(cardid char(4) primary key comment '卡号',balance decimal(10,2) not null comment '余额')engine=innodb charset=utf8 comment '银行卡号表'");
$flag3= $pdo->exec("insert into bank values ('1001',1000),('1002',1)");
if($flag2==0 && $flag3){
$pdo->commit();
echo '数据表创建成功!';
}else{
$pdo->rollBack();
echo '数据表创建失败!';
}
?>
# PDO操作事务
if(!empty($_POST)){
$dsn='mysql:dbname=sel;charset=utf8';
$pdo=new PDO($dsn,'root','');
$out=$_POST['card_out']; //转出卡号
$in=$_POST['card_in']; //注入卡号
$money=$_POST['money']; //金额
$pdo->beginTransaction(); //开启事务
//转账
$flag1=$pdo->exec("update bank set balance=balance-$money where cardid='$out'");
$flag2=$pdo->exec("update bank set balance=balance+$money where cardid='$in'");
//查看转出的账号是否大于0,大于0返回true,否则返回false
$stmt=$pdo->query("select balance from bank where cardid='$out'");
$flag3=$stmt->fetchColumn()>=0?1:0;
if($flag1 && $flag2 && $flag3){
$pdo->commit (); //提交事务
echo '转账成功';
}
else{
$pdo->rollBack (); //回滚事务
echo '转账失败';
}
}
?>
转出卡号:
转入卡号:
金额:
PDO操作预处理
MySQL中的预处理
预处理好处:编译一次多次执行,用来解决一条SQL语句多次执行的问题,提高了执行效率
预处理语句
prepare 预处理名字 from 'sql语句'
执行预处理
execute 预处理名字 [using 变量]
PDO中的预处理
位置占位符 insert into bank values (?,?)
参数占位符 insert into bank values (:p1,:p2)
$stmt->bindParam()和$stmt->bindValue()的区别
$stmt->bindParam() 中的值只能是变量
$stmt->bindValue() 中的值能是变量也可以为值
预处理的好处
提高执行效率
提高安全性
# 位置占位符
$dsn= 'mysql:host=localhost;port=3306;dbname=sel;charset=utf8';
$pdo= new PDO($dsn,'root','');
//创建预处理对象
$stmt=$pdo->prepare("insert into bank values (?,?)"); //?是占位符
//执行预处理
$cards=[
['1003',500],
['1004',100]
];
foreach($cards as $card){
//绑定参数,并执行预处理,
//方法一:
/*
$stmt->bindParam(1, $card[0]); //占位符的位置从1开始
$stmt->bindParam(2, $card[1]);
$stmt->execute(); //执行预处理
*/
//方法二:
/*
$stmt->bindValue(1, $card[0]);
$stmt->bindValue(2, $card[1]);
$stmt->execute();
*/
//方法三:如果占位符的顺序和数组的顺序一致,可以直接传递数组
$stmt->execute($card);
}
echo '数据处理完成';
?>
# 参数占位符
$dsn= 'mysql:host=localhost;port=3306;dbname=sel;charset=utf8';
$pdo= new PDO($dsn,'root','');
//创建预处理对象
$stmt=$pdo->prepare("insert into bank values (:p1,:p2)"); //:p1,:p2是参数占位符
//执行预处理
$cards=[
['p1'=>'1005','p2'=>500],
['p1'=>'1006','p2'=>1000]
];
foreach($cards as $card){
//方法一:
/*
$stmt->bindParam(':p1', $card['p1']);
$stmt->bindParam(':p2', $card['p2']);
$stmt->execute();
*/
//方法二:但数组的下标和参数名一致的时候就可以直接传递关联数组
$stmt->execute($card);
}
echo '数据处理完成';
?>
PDO异常处理
概念
PDOException是PDO的异常类
实例化PDO会自动抛出异常
其他操作不会抛出异常,需要设置PDO的异常模式
PDO异常模式
PDO::ERRMODE_EXCEPTION 抛出异常
PDO::ERRMODE_SILENT 中断
PDO::ERRMODE_WARNING 警告
try{
$dsn='mysql:dbname=data;charset=utf8';
$pdo=new PDO($dsn,'root','');
//这是PDO错误模式属性,PDO自动抛出异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->query('select * from newsssssss'); //自动抛出异常
} catch (PDOException $ex) {
echo '错误信息:'.$ex->getMessage(),'
';
echo '错误文件:'.$ex->getFile(),'
';
echo '错误行号:'.$ex->getLine();
}
?>
单例模式封装MySQL-PDO
分析
单例模式
初始化参数
连接数据库
执行增删改
执行查询
返回二维数组
返回一维数组
返回一行一列
第一部分:单例、初始化参数、实例化PDO
class MyPDO{
private $type; //数据库类别
private $host; //主机地址
private $port; //端口号
private $dbname; //数据库名
private $charset; //字符集
private $user; //用户名
private $pwd; //密码
private $pdo; //保存PDO对象
private static $instance;
private function __construct($param) {
$this->initParam($param);
$this->initPDO();
}
private function __clone() {
}
public static function getInstance($param=array()){
if(!self::$instance instanceof self)
self::$instance=new self($param);
return self::$instance;
}
//初始化参数
private function initParam($param){
$this->type=$param['type']??'mysql';
$this->host=$param['host']??'127.0.0.1';
$this->port=$param['port']??'3306';
$this->dbname=$param['dbname']??'data';
$this->charset=$param['charset']??'utf8';
$this->user=$param['user']??'root';
$this->pwd=$param['pwd']??'root';
}
//初始化PDO
private function initPDO(){
try{
$dsn="{$this->type}:host={$this->host};port={$this->port};dbname={$this->dbname};charset={$this->charset}";
$this->pdo=new PDO($dsn, $this->user, $this->pwd);
} catch (PDOException $ex) {
echo '错误编号:'.$ex->getCode(),'
';
echo '错误行号:'.$ex->getLine(),'
';
echo '错误文件:'.$ex->getFile(),'
';
echo '错误信息:'.$ex->getMessage(),'
';
exit;
}
}
}
//测试
$param=array(
);
$mypdo= MyPDO::getInstance($param);
var_dump($mypdo);
?>
第二部分:数据操作部分
class MyPDO{
private $type; //数据库类别
private $host; //主机地址
private $port; //端口号
private $dbname; //数据库名
private $charset; //字符集
private $user; //用户名
private $pwd; //密码
private $pdo; //保存PDO对象
private static $instance;
private function __construct($param) {
$this->initParam($param);
$this->initPDO();
$this->initException();
}
private function __clone() {
}
public static function getInstance($param=array()){
if(!self::$instance instanceof self)
self::$instance=new self($param);
return self::$instance;
}
//初始化参数
private function initParam($param){
$this->type=$param['type']??'mysql';
$this->host=$param['host']??'127.0.0.1';
$this->port=$param['port']??'3306';
$this->dbname=$param['dbname']??'data';
$this->charset=$param['charset']??'utf8';
$this->user=$param['user']??'root';
$this->pwd=$param['pwd']??'root';
}
//初始化PDO
private function initPDO(){
try{
$dsn="{$this->type}:host={$this->host};port={$this->port};dbname={$this->dbname};charset={$this->charset}";
$this->pdo=new PDO($dsn, $this->user, $this->pwd);
} catch (PDOException $ex) {
$this->showException($ex);
exit;
}
}
//显示异常
private function showException($ex,$sql=''){
if($sql!=''){
echo 'SQL语句执行失败
';
echo '错误的SQL语句是:'.$sql,'
';
}
echo '错误编号:'.$ex->getCode(),'
';
echo '错误行号:'.$ex->getLine(),'
';
echo '错误文件:'.$ex->getFile(),'
';
echo '错误信息:'.$ex->getMessage(),'
';
}
//设置异常模式
private function initException(){
$this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
//执行增、删、改操作
public function exec($sql){
try{
return $this->pdo->exec($sql);
} catch (PDOException $ex) {
$this->showException($ex, $sql);
exit;
}
}
//获取自动增长的编号
public function lastInsertId(){
return $this->pdo->lastInsertId();
}
}
//测试
$param=array(
);
$mypdo= MyPDO::getInstance($param);
//echo $mypdo->exec('delete from news where id=6');
if($mypdo->exec("insert into news values (null,'11','1111',unix_timestamp())"))
echo '自动增长的编号是:'.$mypdo->lastInsertId ();
?>
第三部分:数据查询部分
class MyPDO{
...
//判断匹配的类型
private function fetchType($type){
switch ($type){
case 'num':
return PDO::FETCH_NUM;
case 'both':
return PDO::FETCH_BOTH;
case 'obj':
return PDO::FETCH_OBJ;
default:
return PDO::FETCH_ASSOC;
}
}
//获取所有数据 ,返回二维数组
public function fetchAll($sql,$type='assoc'){
try{
$stmt=$this->pdo->query($sql); //获取PDOStatement对象
$type= $this->fetchType($type); //获取匹配方法
return $stmt->fetchAll($type);
} catch (Exception $ex) {
$this->showException($ex, $sql);
}
}
//获取一维数组
public function fetchRow($sql,$type='assoc'){
try{
$stmt=$this->pdo->query($sql); //获取PDOStatement对象
$type= $this->fetchType($type); //获取匹配方法
return $stmt->fetch($type);
} catch (Exception $ex) {
$this->showException($ex, $sql);
exit;
}
}
//返回一行一列
public function fetchColumn($sql){
try{
$stmt=$this->pdo->query($sql);
return $stmt->fetchColumn();
} catch (Exception $ex) {
$this->showException($ex, $sql);
exit;
}
}
}
//测试
$param=array(
);
$mypdo= MyPDO::getInstance($param);
//echo $mypdo->exec('delete from news where id=6');
/*
if($mypdo->exec("insert into news values (null,'11','1111',unix_timestamp())"))
echo '自动增长的编号是:'.$mypdo->lastInsertId ();
*/
//$list=$mypdo->fetchAll('select * from news');
//$list=$mypdo->fetchRow('select * from news where id=1');
$list=$mypdo->fetchColumn('select count(*) from news');
echo '
';
var_dump($list);
?>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。