PHP PDO学习小结
1、PDO概述
PDO(PHP Data Object),是一种以纯面向对象方式实现的数据库操作扩展。
PDO库中有3个类:PDO、PDOStatement、PDOException
PDO常用方法:
- PDO::__construct() :实例化PDO对象
- PDO::exec():SQL写操作,返回影响行数
- PDO::query():SQL读操作,返回PDOStatement类对象(结果集)
- PDO::errorCode()、PDO::errorInfo():获取错误编码和错误描述信息
- PDO::lastInsertId()获取插入操作的最后一个id
2、PDO实例化对象
PDO::__construct ( string $dsn
[, string $username
[, string $password
[, array $driver_options
]]] )
- dsn:包含了请求连接到数据库基本信息的字符串:$dsn='mysql:host=localhost;port=3306;dbname=demo';
- username:用户名
- password:密码
- drivers:PDO属性设置,是关联数组,利用PDO内部常量进行设置,一般不用设置
new PDO('mysql:host=localhost;port=3306;dbname=demo','root','root');
3、SQL语句执行和出错判定
$dsn = 'mysql:host=localhost;port=3306;dbname=demo'; $user = 'root'; $password = 'root'; $pdo = new PDO($dsn, $user, $password); echo '<pre>'; $sql = "set names utf8"; $row = $pdo->exec($sql); var_dump($row); if($row === false){ //因为$row可能为0,故要判断全等 die("SQL Error: {$pdo->errorCode()} {$pdo->errorInfo()[2]}"); } $sql = 'select * from students'; $stmt = $pdo->query($sql) or die("SQL Error: {$pdo->errorCode()} {$pdo->errorInfo()[2]}"); var_dump($stmt);
4、数据库查询结果集处理
获取结果集下一行:
mixed PDOStatement::fetch ([ int
$fetch_style
[, int $cursor_orientation
= PDO::FETCH_ORI_NEXT [, int $cursor_offset
= 0 ]]] )获取结果集所有行:
array PDOStatement::fetchAll ([ int $fetch_style
[, mixed $fetch_argument
[, array $ctor_args
= array() ]]] )
fetch_style:
控制下一行如何返回给调用者,下面是fetch_style的部分取值
- PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组
- PDO::FETCH_BOTH(默认):返回一个索引为结果集列名和以0开始的列号的数组
- PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组
- PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象
function pdo_fatch($stmt,$all = true){ if($all){ return $stmt->fetchAll(PDO::FETCH_ASSOC); }else{ return $stmt->fetch(PDO::FETCH_ASSOC); } }
5、PDO事务
事务:一种原子操作,批量执行多条命令,只有每一条命令都成功执行才能提交结果,否则回滚结果;
- PDO::beginTransaction():开启事务
- PDO::exex():执行事务
- PDO::rollBack():回滚所有操作
- PDO::commit():提交事务执行结果
$dsn = 'mysql:host=localhost;port=3306;dbname=demo'; $user = 'root'; $password = 'chz'; $pdo = new PDO($dsn, $user, $password); $pdo->beginTransaction() or die('开启事务失败!'); $pdo->exec("insert into students values(null,'tst1',23)"); //设置回滚点 $pdo->exec('savepoint sp1'); $pdo->exec("insert into students values(null,'tst2',32)"); $pdo->exec('rollback to sp1'); $pdo->commit(); //$pdo->rollback();
也可以直接使用底层SQL语句实现事务
$pdo->exec('start transaction'); //开启事务 $pdo->exec('commit'); //提交事务 $pdo->exec('rollback'); //回滚事务
6、PDO错误机制
PDO提供3种错误机制,是通过PDO常量PDO::ATTR_ERRMODE来选择的
- PDO::ERRMODE_SILENT:静默模式,不处理出错(默认模式)
- PDO::ERRMODE_WARNING:警告模式,出错后给出错误提示
- PDO::ERRMODE_EXCEPTION:异常模式,出错后交给PDOException对象处理
PDO::setAttribute()函数可以设置错误处理机制
$dsn = 'mysql:host=localhost;port=3306;dbname=demo'; $user = 'root'; $password = 'chz'; $pdo = new PDO($dsn, $user, $password); $pdo->exec("set names utf8"); //使用默认模式 $sql = "insert int students values()"; $pdo->exec($sql); //不会报错 //切换到警告模式 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); $sql = "insert int students values()"; $pdo->exec($sql); //给出警告Fatal error: Uncaught PDOException: SQLSTATE[42000] //切换到异常模式 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $sql = "insert int students values()"; try{ $pdo->exec($sql); }catch(PDOException $e){ die("代码运行错误:file:{$e->getFile()} line {$e->getLine()} {$e->getMessage()}"); //异常处理 }
此外也可以在PDO实例化时提供第四个参数设定错误处理模式,数据库连接时也应该进行异常处理:
$dsn = 'mysql:host=localhost;port=3306;dbname=demo'; $user = 'root'; $password = 'chz'; $drivers = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ); try{ $pdo = new PDO($dsn, $user, $password, $drivers); }catch(PDOException $e){ die("数据库连接失败!{$e->getMessage()}"); } $sql = "set names utf8"; try{ $pdo->exec($sql); }catch(PDOException $e){ die("代码运行错误:file:{$e->getFile()} line {$e->getLine()} {$e->getMessage()}"); }
7、PDO预处理
常用函数:
- PDO::prepare():发送预处理指令,只需提供sql语句,不需要prepare 预处理名字 from,成功返回PDOStstement对象
- PDOStatement::bindParam():绑定参数,只能绑定变量(引用传递)
- PDOStatement::bindValue():绑定参数值(值传递)
- bool PDOStatement::execute():执行预处理,也可以绑定参数值
占位符:使用mysql原生占位符问号(?)或使用PDO特定预处理参数指令冒号加参数名(:name)
//使用问号占位符占位 $pre_sql = "select * from students where id=?"; $stmt = $pdo->prepare($pre_sql); $stmt->bindValue(1,20); //1表示第一个占位符,20是占位符取值 $stmt->execute(); print_r($stmt->fetchAll(PDO::FETCH_ASSOC)); //execute函数使用索引数组绑定参数 $stmt->execute(array(22)); print_r($stmt->fetchAll(PDO::FETCH_ASSOC)); //使用冒号加参数名占位 $pre_sql = "select * from students where age between :min and :max"; $stmt = $pdo->prepare($pre_sql); //值传递绑定参数方式 $min = 2; $max = 4; $stmt->bindValue(':min',$min); $stmt->bindValue(':max',$max); for($i = 0; $i < 3; $i++){ $stmt->execute(); print_r($stmt->fetchAll(PDO::FETCH_ASSOC)); //每次执行结果都一样 $min += 2; $max += 2; } //引用传递绑定参数方式 $min = 2; $max = 4; $stmt->bindParam(':min',$min); $stmt->bindParam(':max',$max); for($i = 0; $i < 3; $i++){ $stmt->execute(); print_r($stmt->fetchAll(PDO::FETCH_ASSOC)); //每次执行结果会根据$min和$max变化而变化 $min += 2; $max += 2; } //execute函数使用关联数组绑定参数 $stmt->execute(array(':min'=>3,':max'=>6)); print_r($stmt->fetchAll(PDO::FETCH_ASSOC));