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 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>";

?>