PHP中PDO数据库操作类
一、PDO的介绍
1、PDO(PHP Data Object) 是PHP 5新出来的东西,在PHP 6都要出来的时候,PHP 6只默认使用PDO来处理数据库,将把所有的数据库扩展移到了PECL,那么默认就是没有了我们喜爱的php_mysql.dll之类的了,那怎么办捏,我们只有与时俱进了。
2、PDO是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么php_mysql.dll、php_pgsql.dll、php_mssql.dll、php_sqlite.dll等等扩展来连接MySQL、PostgreSQL、MS SQL Server、SQLite,同样的,我们必须借助 ADOdb、PEAR::DB、PHPlib::DB之类的数据库抽象类来帮助我们,无比烦琐和低效,毕竟,php代码的效率怎么能够我们直接用C/C++写的扩展斜率高捏?
所以嘛,PDO的出现是必然的,大家要平静学习的心态去接受使用,也许你会发现能够减少你不少功夫哦。
二、PDO的安装
在windows下在 php\ext 下能找到相应的dll文件,然后在php.ini中进行配置才能使用各类的数据库函数操作,在Linux下的编译PHP是加上PDO选项
下面的在windows的php.ini配置文件的各类配置选项
extension=php_pdo.dll
extension=php_pdo_firebird.dll
extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_oci8.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll
三、使用PDO进行数据库的操作
1. PDO 提供了两个类:
a) PDO 类:和数据库连接有关的操作。
b) PDOstatement 类:处理SQL 和结果集。(PDO预处理类)
2. 连接数据的功能:
a) 创建PDO 对象:
$pdo=new PDO(‘mysql:host=localhost;dbname=bbs’,’username’,’pass’);
b) pdo 用try….catch…..自动捕获异常。
Try{
$pdo=new PDO(‘mysql:host=localhost;dbname=bbs’,’username’,’pass’);
}catch(PDOException $e){
Echo ‘连接失败’.$e->getMessage();
Exit;
}
3. PDO 内部的属性(常量)
a) 得到属性的方法 getAttribute(属性);
b) PDO::ATTR_SERVER_INFO 服务器信息
PDO::ATTR_SERVER_VERSION 服务器版本
PDO::ATTR_AUTOCOMMIT 自动提交开启状态
PDO::ATTR_ERRMODE 错误模式
PDO::ATTR_PERSISITENT 是否持久连接
c) 设置属性的方法 setAttribute(属性);
d) 设置属性的另一种方法:
$arr=array(PDO::ATTR_AUTOCOMMIT=>1,PDO::ATTR_PERSISTENT=>1);
$pdo=new PDO(‘mysql:host=localhost;dbname=bbs’,’username’,’pass’,$arr);
$arr 设置底层驱动调优的参数
4. PDO 中的三种错误模式
a) 三种模式
PDO::ERRMODE_SILENT 常规模式(默认模式无显示错误信息,手动用方法获取)
PDO::ERRMODE_WARNING 警告模式
PDO::ERRMODE_EXCEPTION 异常模式
b) 获取错误信息的方法
errorCode()
errorInfo()返回的数组
c) 设置警告模式的方法
setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
5. 语句的分类;
a) 有影响行的语句:update、insert delete create 用 exec( )函数执行。
b) 有结果集的语句:select、desc、show ….用query()函数执行。
c) Exec()返回影响的行数int。
d) Query()返回结果集。返回的是object 类型。可以用foreach 遍历。
6. PDO 的事物处理功能
第一步:关闭自动提交的属性。setAttribute(PDO::ATTR_AUTOCOMMIT,0);
第二步:开启事务处理模式。beginTransaction();
第三步:执行事务中多条存在业务关联的语句。
Try{}语句中进行业务逻辑判断,如果有异常利用throw 抛给catch 进行异常处理,如果无异常,
语句执行成功并且有影响行,则执行commit()。
Catch 中捕获异常,利用rollback()进行sql 语句执行的回滚,回到出现异常之前的状态。
第四步:开启自动提交的属性.setAttribute(PDO::ATTR_AUTOCOMMIT,1);
7. PDO 的预处理的功能
a) PDO 提供的两种占位使用的参数。 ? 和 : name
b) 两种形式:
$pdo->prepare(insert into user(username,age,sex) values(?,?,?));
$pdo->prepare(insert into user(username,age,sex) values(: username,: age,: sex));
c) 绑定参数
------ ?参数的绑定
$stmt->bindParam(1,$username,PDO::PARAM_STR);
$stmt->bindParam(2,$age,PDO::PARAM_INT);
$stmt->bindParam(3,$sex,PDO::PARAM_STR);
------ : name 参数的绑定
$stmt->bindParam(‘:username’,$username);
$stmt->bindParam(‘:age’,$age);
$stmt->bindParam(‘:sex’,$sex);
d) 给绑定好的参数赋值
$username=’liiu’;
$age=20;
$sex=’nan’;
e) 执行语句。
$stmt->execute();
f) 获得影响的行数或者结果集。
$stmt->rowCount( );
g) 绑定参数的简化。
$stmt->execute(array(‘liu’,29,’nan’)); 绑定执行集于一身用于?号占位符
h)可以用户直接接收表单的值,只要表单的名字和数据库中的字段保持相同
$_POST=array(‘username’=>’liu’,’age’=>20,sex=>’nan’);
$stmt->execute($_POST);
8.PDO fetch 方式获得结果集中的记录
$stmt->setFetchMode(PDO::FETCH_NUM);设置fetch 获取结果的类型,此取出来的结果是索引数组,这能影响全部的SQL语句
$row=$stmt->fetch(PDO::FETCH_ASSOC);直接在获取时设置类型,只影响一条SQL语句
$row=$stmt->fetch(PDO::FETCH_NUM);
$row=$stmt->fetch(PDO::FETCH_BOTH);
$row=$stmt->fetch(PDO::FETCH_OBJECT);
$row=$stmt->fetchall(参数与上相同);直接获得所有结果集的二维数组
9.绑定方式 bindcolumn 获取结果集中的记录
$stmt=$pdo->prepare(‘select username,age,sex from user where id >?’);
$stmt->bindColumn(1,$username);
$stmt->bindColumn(2,$age)
$stmt->bindColumn(3,$sex);
$stmt->execute(array(3));
While($stmt->fetch()){
Echo $username.$age.$sex;
}
Echo ‘行数’.$stmt->rowcount();
四、相应的代码实例
1、建立数据库的连接和设置性能调优参数的方法
<?php try{ $driver_opts=array(PDO::ATTR_AUTOCOMMIT=>0, PDO::ATTR_PERSISTENT=>true);//这是MySQL的性能调优参数的设置 $pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456", $driver_opts); //新建连接数据库的PDO对象 $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0); //设置不进行自动提交 $pdo->setAttribute(PDO::ATTR_PERSISTENT, true); //设置长连接为真 }catch(PDOException $e){ echo "数据库连接失败:".$e->getMessage(); //有异常就会输出错误的信息 exit; } //PDO::getAttribute — Retrieve a database connection attribute //得到数据库连接状态的方法函数,这里有很多的参数,具体看PHP手册 echo $pdo->getAttribute(PDO::ATTR_PERSISTENT)."<br>"; //得到是否建立长连接 echo $pdo->getAttribute(PDO::ATTR_AUTOCOMMIT)."<br>"; //得到是否自动提交 echo $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION)."<br>"; //得到客户端的信息 echo $pdo->getAttribute(PDO::ATTR_SERVER_INFO)."<br>"; //得到数据库的信息 echo $pdo->getAttribute(PDO::ATTR_SERVER_VERSION)."<br>"; //得到数据库的版本 echo $pdo->getAttribute(PDO::ATTR_DRIVER_NAME)."<br>"; //得到驱动的名字 ?>
2、PDO对象的方法使用之处理没有结果集的情况,执行SQL语句使用exec()
<?php
try{
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456");
}catch(PDOException $e){
echo "数据库连接失败:".$e->getMessage();
exit;
}
//执行SQL语句 exec() query() prepare()
//一是有结果集的query(), 执行select语句
//exec()用来执行有影响行数的,update, delete insert, other
//exec()返回的是影响的行数
$affected_rows=$pdo->exec("insert into shops(name1, price, num, desn) values('aa', '12.1', '10', 'good')");
echo "影响的行数".$affected_rows;
//设置错误报告模式
print_r($pdo->errorInfo());
if(!$affected_rows){
echo $pdo->errorCode()."<br>";
print_r($pdo->errorInfo());
}else{
echo "执行成功!";
}
/*一般这样的处理错误的报告
try{
$affected_rows=$pdo->exec("insert into shops(name1, price, num, desn) values('aa', '12.1', '10', 'good')");
echo "最后插入的自动增长的ID:".$pdo->lastInsertId();
}catch(PDOException $e){
echo $e->getMessage();
}
*/
?>
3、PDO对象的方法使用之处理有结果集的情况,执行SQL语句使用query()
<?php
try{
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo "数据库连接失败:".$e->getMessage();
exit;
}
//执行SQL语句 exec() query() prepare()
//一是有结果集的query(), 执行select语句
//exec()用来执行有影响行数的,update, delete insert, other
//exec()返回的是影响的行数
try{
$stmt=$pdo->query("select * from shops");
foreach($stmt as $row){
print_r($row);
echo '<br>';
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
4、PDO事物处理
<?php
try{
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456", array(PDO::ATTR_AUTOCOMMIT=>0));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo "数据库连接失败:".$e->getMessage();
exit;
}
/*
*
* 事务处理
*
* 张三从李四那里买了一台 2000 元的电脑
*
* 从张三帐号中扣出 2000元
*
* 向李四账号中加入 2000元
*
* 从商品表中减少一台电脑
*
* MyIsAM不支持事务处理 InnoDB支持事物处理
*
*/
try{
$pdo->beginTransaction(); //启动一个事物处理
$price=500;
$sql="update zhanghao set price=price-{$price} where name='zhangsan'";
$affected_rows=$pdo->exec($sql);
if(!$affected_rows)
throw new PDOException("张三转出失败");
$sql="update zhanghao set price=price+{$price} where name='lisi'";
$affected_rows=$pdo->exec($sql);
if(!$affected_rows)
throw new PDOException("向李四转入失败");
echo "交易成功!";
$pdo->commit(); //确认提交,这样就不能回滚了
}catch(PDOException $e){
echo $e->getMessage();
$pdo->rollback(); //有异常进行回滚处理
}
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); //关闭自动提交
?>
5、PDO的预处理
<?php
try {
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456");
}catch(PDOException $e){
echo $e->getMessage();
}
/* pdo中有两种占位符号
*
* ? 参数 --- 索引数组, 按索引顺序使用
* 名子参数 ----关联数组, 按名称使用,和顺序无关
*/
$stmt=$pdo->prepare("insert into shops(name, price, num, desn) values(?, ?, ?, ?)"); //所有SQL都可执行
//准备好了一条语句,并入到服务器端,也已经编译过来了,就差为它分配数据过来
// $stmt=$pdo->prepare("insert into shops(name, price, num, desn) values(:name,:price, :num, :desn)");
//绑定参数
/* $stmt->bindParam(":name", $name);
$stmt->bindParam(":num", $num);
$stmt->bindParam(":desn", $desn);
$stmt->bindParam(":price", $p);
*/
//绑定参数
$stmt->bindParam(1, $name, PDO::PARAM_STR);
$stmt->bindParam(3, $num, PDO::PARAM_INT);
$stmt->bindParam(4, $desn, PDO::PARAM_STR);
$stmt->bindParam(2, $p, PDO::PARAM_STR);
$name="wwww1";
$num=101;
$desn="hello1";
$p=34.51;
// 绑定执行集于一身用于?号占位符,要按照相应的顺序name, price, num, desn
$stmt->execute(array("myname1", 11.2, 55, "very good"));
$stmt->execute(array("myname2", 11.2, 54, "very good"));
$stmt->execute(array("myname3", 11.2, 56, "very good"));
/*
//绑定执行于一身的 :name 占位符
$stmt->execute(array(":price"=>99, ":name"=>"kkk1", ":num"=>"451", ":desn"=>"aaaaaa1"));
$stmt->execute(array(":price"=>88, ":name"=>"kkk2", ":num"=>"452", ":desn"=>"aaaaaa2"));
$stmt->execute(array(":price"=>77, ":name"=>"kkk3", ":num"=>"453", ":desn"=>"aaaaaa3"));
*/
if($stmt->execute()){
echo "执行成功";
echo "最后插入的ID:".$pdo->lastInsertId();
}else{
echo "执行失败!";
}
?>
6、PDO fetch方式获得结果集中的记录
<?php
try {
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456");
}catch(PDOException $e){
echo $e->getMessage();
}
//获取结果 fetch() fetchAll();
$stmt=$pdo->prepare("select id, name, price, num, desn from shops where id > :id order by id");
$stmt->execute(array(":id"=>100));
$stmt->setFetchMode(PDO::FETCH_ASSOC);
/*
while($row=$stmt->fetch()){
print_r($row);
echo '<br>';
}
*/
$data=$stmt->fetchAll(); //取出所有的数据
echo '<pre>';
print_r($data);
echo '</pre>';
?>
7、绑定方式 bindcolumn 获取结果集中的记录
<?php
try {
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456");
}catch(PDOException $e){
echo $e->getMessage();
}
//获取结果 fetch() fetchAll();
$stmt=$pdo->prepare("select id, name, price, num, desn from shops where id > :id order by id");
$stmt->bindColumn("id", $id, PDO::PARAM_INT);
$stmt->bindColumn("price", $price);
$stmt->bindColumn("name", $name, PDO::PARAM_STR);
$stmt->bindColumn(4, $num);
$stmt->bindColumn(5, $desn);
$stmt->execute(array(":id"=>100));
for($i=0; $i<$stmt->columnCount(); $i++){
$field=$stmt->getColumnMeta($i); //得到字段的信息
echo $field["name"]."---"; //输出字段的名字
}
echo '<br>';
while($stmt->fetch()){
echo "$id---$name---$price----$num------$desn<br>";
}
echo "总记录数:".$stmt->rowCount()."<br>";
echo "总字段数:".$stmt->columnCount()."<br>";
?>
8、表格的形式输出
<?php
try {
$pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123456");
}catch(PDOException $e){
echo $e->getMessage();
}
//获取结果 fetch() fetchAll();
$stmt=$pdo->prepare("select id, name, price, num, desn from shops where id > :id order by id");
$stmt->bindColumn("id", $id, PDO::PARAM_INT);
$stmt->bindColumn("price", $price);
$stmt->bindColumn("name", $name, PDO::PARAM_STR);
$stmt->bindColumn(4, $num);
$stmt->bindColumn(5, $desn);
$stmt->execute(array(":id"=>100));
echo '<table border=1 width=900 align="center">';
echo '<tr>';
for($i=0; $i<$stmt->columnCount(); $i++){
$field=$stmt->getColumnMeta($i);
echo '<th>'.$field["name"]."</th>";
}
echo '</tr>';
while($stmt->fetch()){
echo '<tr>';
echo '<td>'.$id.'</td>';
echo '<td>'.$name.'</td>';
echo '<td>'.$price.'</td>';
echo '<td>'.$num.'</td>';
echo '<td>'.$desn.'</td>';
echo '</tr>';
}
echo '</table>';
echo "总记录数:".$stmt->rowCount()."<br>";
echo "总字段数:".$stmt->columnCount()."<br>";
?>