【转】 PDO使用归纳【PHP】
【任務】將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 ¶m [,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();??
}??
?>
更多屬性和詳細介紹參:http://hi.baidu.com/traindiy/blog/item/06fd2b3f204fdce755e7232d.html
另,參考:http://hi.baidu.com/traindiy/blog/item/c3ff98453ec873348694732c.html
http://hi.baidu.com/traindiy
總結
以上是生活随笔為你收集整理的【转】 PDO使用归纳【PHP】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Standard C Library -
- 下一篇: ×××网络连接安全性以及协议支持介绍