PDO使用归纳

 

为什么你应该使用PHP PDO访问数据库

PDO 使用归纳【 PHP

2010 02 27 星期六 18:09

【任务】将 PDO 封装成类

new PDO("mysql:host=localhost;dbname=php100","root","pwd" [,driverOptions]);
如果需要长连接,需要长最后一个参数 driverOption persistent:/aj/ 持续的,不断的
new PDO(" 连接信息 ","root","pwd",array(PDO::ATTR_PERSISTENT=>true));
使用 array() 来传入最后一个参数,是可以带多个选项值, 如:
$pdo = new PDO('mysql:host=localhost;dbname=forum','root','123456',array(
PDO::ATTR_PERSISTENT=>TRUE , PDO::ATTR_CASE=>PDO::CASE_UPPER , PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION ));
上面分别指定了:长连接开启,强制 PDO 获取的列字符大写,以及使用 PDOException 抛出异常。
对于这个属性参数,也可以用 setAttribute 来更改,如下:
$pdo->setAttribute(PDO::ATTR_CASE,
PDO::CASE_LOWER );
那么接下去就可以用 $row['city'] 来访问列值,而不必要用 $row['CITY'] 大写方式来访问。

PDO 常用方法:
PDO::query()  
主要用于有记录结果返回的操作,特别是 select 操作。
PDO::exec()
主要是针对没有结果集合返回的操作。如 insert,update 等操作。返回影响行数。
PDO::lastInsertId()
返回上次插入操作最后一条 ID 但要注意:如果用 insert into tb(col1,col2) values(v1,v2),(v11,v22).. 的方式一次插入多条记录, lastinsertid() 返回的只是第一条 (v1,v2) 插入时的 ID, 而不是最后一条记录插入的记录 ID
PDOStatement::
fetch() 是用来获取一条记录。配合 while 来遍历。
PDOStatement::
fetchAll() 是获取所有记录集到一个中。
PDOStatement:: fetchcolumn([int column_indexnum])   用于直接访问列,参数 column_indexnum 是该列在行中的从 0 开始索引值,但是,这个方法一次只能取得同一行的一列,只要执行一次,就跳到下一行。 因此,用于直接访问某一列时较好用,但要遍历多列就用不上。
PDOStatement::
rowcount() 适用于当用 query("select ...") 方法时,获取记录的条数。也可以用于预处理中。 $stmt->rowcount();
PDOStatement::
columncount() 适用于当用 query("select ...") 方法时,获取记录的列数。

注解:
1
、选 fetch 还是 fetchall
小记录集时,用 fetchall 效率高,减少从数据库检索次数,但对于大结果集,用 fetchall 则给系统带来很大负担。数据库要向 WEB 前端传输量太大反而效率低。
2
fetch() fetchall() 有几个参数:
mixed pdostatement::fetch([int fetch_style [,int cursor_orientation [,int cursor_offset]]])

array pdostatement::fetchAll(int fetch_style)

fetch_style 参数 :
$row=$rs- >fetchAll(PDO::FETCH_BOTH ); FETCH_BOTH 是默认的,可省,返回关联和索引。
$row=$rs- >fetchAll(PDO::FETCH_ASSOC ); FETCH_ASSOC 参数决定返回的只有关联数组。
$row=$rs- >fetchAll(PDO::FETCH_NUM ); 返回索引数组
$row=$rs- >fetchAll(PDO::FETCH_OBJ ); 如果 fetch() 则返回对象,如果是 fetchall(), 返回由对象组成的二维数组,如:
Array
(
    [0] => stdClass Object
        (
            [cityid] => 2
            [city] =>
福州
            [countryid] => 1
        )

    [1] => stdClass Object
        (
            [cityid] => 3
            [city] =>
厦门
            [countryid] => 1
        )
...
);
遍历:
foreach($row as $r)
{
echo "{$r->cityid}
:城市 {$r->city}.<br />";
//
echo "{$r[0]} :城市 {$r[1]}.<br />";
}
$row=$rs- >fetch(PDO::FETCH_LAZY ); FETCH_LAZY 返回对象:如:
PDORow Object
(
    [queryString] => select * from city
    [cityid] => 2
    [city] =>
福州
    [countryid] => 1
)
$row = $stmt- >fetch(PDO::FETCH_BOUND ); 用于使 fetch 返回 true ,并将获取的列值赋给 bindParam ()方法中指定的相应变量。参考最后一个示例。 ---- 相当于 mysqli 绑定到结果。
-----------------------------------------------
例:概要
$rs=$db->query("select * from php100");
while($row = $rs->fetch())
{
print_r($row);
}
或不使用 while 来遍历:
$rs=$db->query("select * from php100");
$row=$rs->fetchall();
print_r($row);

$db->exec('insert into ...');
------------------------------------------------
例: select 遍历记录和取得记录总数

try{
$pdo = new PDO("mysql:host=localhost;dbname=forum","root","123456");
}catch(PDOException $e){
echo '
连接错误: '.$e->errorcode();
}

$q="select * from city";
$rs=$pdo->query($q);
$row=$rs->fetchAll();
foreach($row as $r)
{
echo "{$r['cityid']}
:城市 {$r['city']}.<br />";
//
echo "{$r[0]} :城市 {$r[1]}.<br />";
}
echo " 共有 {$rs->rowcount()} 条记录 " //$rs->rowcount() 返回行数。

返回的数组格式:可以看到,每一组都带有关联和索引的两种形式:
Array
(
    [0] => Array
        (
            [cityid] => 2
            [0] => 2
            [city] =>
福州
            [1] =>
福州
            [countryid] => 1
            [2] => 1
        )

    [1] => Array
        (
            [cityid] => 3
            [0] => 3
            [city] =>
厦门
            [1] =>
厦门
            [countryid] => 1
            [2] => 1
        )
)

如果用: while($row = $rs->fetch()){ print_r($row);}
while
返回的每一个数组格式是:
Array
(
    [cityid] => 2
    [0] => 2
    [city] =>
福州
    [1] =>
福州
    [countryid] => 1
    [2] => 1
)
可以看到:
$rs->fetch()
一次返回一个,
$rs->fetchAll()
一次返回所有的记录,
两者相同的是:都可以用索引数组或关联数组来取得最终字段值,
两者不同的是, fetchAll() 返回的是二维数组。可以用 foreach 遍历。


-----------------------------
例:插入记录
$affectedrows = $pdo->exec("insert into city(cityid,city,countryid) values(NULL,'
北京 ',2),(NULL,' 南京 ',2)");
echo '
共影响行数: '.$affectedrows.'<br />';
echo '
最后插入的记录 ID 为: '.$pdo->lastinsertid();
这里当用 insert into city(cityid,city,countryid) values(NULL,' 北京 ',2) 时,返回的正确的 ID 值,但按上例的方法插入多条记录,则返回的依旧是北京那一条记录的 ID ,解决办法是把这个值 lastinsertid()+ 行数 -1


------------------------------
例:返回 exec query 错误
把上例的 insert 随便改一个,使插入错误,再加上一行:
print_r(
$pdo->errorinfo() );
返回:数组 0 表示存储 SQL 标准中定义的 SQLSTATE 码。 1 表示错误码, 0 表示错误消息 , 这里是指 city 表插入的外键在 country 表中不存在。
Array
(
    [0] => 00000
    [1] => 1452
    [2] => Cannot add or update a child row: a foreign key constraint fails (`forum`.`city`, CONSTRAINT `FK_city_country` FOREIGN

KEY (`countryid`) REFERENCES `country` (`country_id`))
)

***************************************************************
PDO
的预处理:准备语句

0 、连接: $pdo = new PDO(....);
1
、准备:查询和 mysqli 的方式不同,支持两种参数占位方式: 问号参数 命名参数 “: 字段名 ”; 命名参数更明确。
     $q="insert into city(city,countryid) values(?,?)"; //
$q = "insert into city(city,countryid) values(:city,:countryid)"; 
     $stmt = $pdo->prepare($q);
2
、执行 execute $pdo->lastinsertid(); 对预处理也是可用的。
  
有两种方式:注意两种方式用 问号参数 绑定时有不同的 execute 占位引用方式。并且偏移基数不同。
   
1 )显式地把参数值做为参数传给 execute: boolean PDOSTatement::execute([array input_parameters])
     
命名参数方式 :      
        $q = "insert into city(city,countryid) values(:city,:countryid)";
        $stmt = $pdo->prepare($q);
        $stmt->execute(array(':city'=>'
太原 ',':countryid'=>'2'));// 本条可多次执行。注意, countryid 是数值型,但也要用单引号来包住。
     
问号参数 :
      $q = "insert into city(city,countryid) 
values(?,?)";
      $stmt = $pdo->prepare($q);
      $stmt->execute
(array('0'=>' 武汉 ','1'=>'2'));  // 注意这里不是用 '?' 的方式,而是用上面占位符的 0 开始 的索引偏移

    2 )绑定参数。 boolean PDOSTatement::bindParam(mixed parameter,mixed &variable [,int datatype [,int length [,mixed driver_option]]])
       mixed parameter
是占位符, 当用?问号参数时, parameter 是占位符的 1 开始 的索引偏移, 而不是 ,这和 MYSQLI 的预处理不相同。

       variable 是绑定的变量值
       datatype
有以下几种类型:
         PDO_PARAM_BOOL 布尔类型。
         PDO_PARAM_input_output
参数传给存储过程时使用此类型,可以在过程执行后修改。
         PDO_PARAM_INT
整型。
         PDO_PARAM_NULL NULL
类型。
         PDO_PARAM_LOG  
大对象类型。
         PDO_PARAM_STMT   PDO
对象类型,当前不可操作。
         PDO_PARAM_STR   char,varchar
和其它字符串类型。
       length
指定数据类型长度。 只有当赋为 PDO_PARAM_input_output 类型时才需要此参数。
      driver_option
用来传递任何数据库驱动程序特定的选项。
  
如:
       $q = "insert into city(city,countryid) values(?,?)";
       $stmt = $pdo->prepare($q);

       $city=' 大连 ';
       $country=1;
       
       $stmt->bindparam(1,$city); //
注意这里 parameter 不是用 “' '” 方式。并且从 1 开始偏移。
       $stmt->bindparam(2,$country);

       $stmt->execute();

---------------------
预处理的绑定列:
boolean PDOStatement::bindcolum(mixed column_index,mixed &param [,int type [,int maxlen[,mixed driver_options]]]);
参数 column_index 是要绑定的行中列偏移, 1 开始 。当然也可以用列名。 type 就用来设置类型限制变量值,如 PDO::PARAM_STR 是限制文本,具体参 bindParam() 。通过 maxlen 限制其长度。
try{
$pdo = new PDO("mysql:host=localhost;dbname=forum","root","123456");
}catch(PDOException $e){
echo '
连接错误: '.$e->errorcode();
}

$q="select * from city";
$stmt=$pdo->prepare($q);
$stmt->execute();
$rscount=$stmt->rowcount(); // 总记录数

$stmt->bindcolumn(1,$cityid);
$stmt->bindcolumn('city',$city,PDO::PARAM_STR,1);
$stmt->bindcolumn(2,$countryid);

for($i=1;$i<=$rscount;$i++)
{
   $row = $stmt->fetch(PDO::FETCH_BOUND);
   printf("%s
ID 是: %s ",$city,$cityid);
   echo '<hr />';
}

**********************************************************
PDO 处理事务:
PDO->__construct()
方法的作用是建立一个 PDO 链接数据库的实例。    
PDO->beginTransaction()
PDO->commit() PDO->rollBack() 这三个方法是在支持回滚功能时一起使用的。 PDO->beginTransaction() 方法标明起始点, PDO->commit() 方法标明回滚结束点,并执行 SQL PDO->rollBack() 执行回滚。    
<?php   
try {   
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', '');   
    $dbh->query('set names utf8;');   
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   
    
$dbh->beginTransaction();    
    $dbh->exec("INSERT INTO `test`.`table` (`name` ,`age`)VALUES ('mick', 22);");   
    $dbh->exec("INSERT INTO `test`.`table` (`name` ,`age`)VALUES ('lily', 29);");   
    $dbh->exec("INSERT INTO `test`.`table` (`name` ,`age`)VALUES ('susan', 21);");   
  
 $dbh->commit();   
       
} catch (Exception $e) {   
  
 $dbh->rollBack();    
    echo "Failed: " . $e->getMessage();   
}   
?>

 

你可能感兴趣的:(mysql,数据库,exception,query,insert,数据库驱动程序)