作者 主題: PDO 基本用法  (閱讀 47411 次)

0 會員 與 2 訪客 正在閱讀本文。

梁楓

  • 俺是博士!
  • *****
  • 文章數: 6220
    • 檢視個人資料
PDO 基本用法
« 於: 2007-09-14 05:54 »
實在睡不著...痛苦啊...
不過睡不著的時候,最好的方式就是做一些想讓人睡覺的事...

那,就來分享一篇吧...

PHP 自 PHP 5 後內建以經沒有 MySQL 模組了
資料庫的部份從本來的 MySQL 轉而建議使用 PDO
PDO 是什麼呢?就是 PHP Data Object

你可以把它看做是 PHP 版的 adodb
雖然我覺得還不夠 adodb 那麼方便
但是有想要考PHP認證的朋友也要注意了
PDO 已經變成 PHP5 認證中資料庫部份的主要考題

PDO 要怎麼用呢?
首先,我們要在 PHP 安裝時安裝 PDO 模組
而PDO 模組中,又有所謂的 PDO_Drivers
也就是安裝PDO模組後,也需要針對想使用的Database安裝不用的驅動模組

我個人喜歡使用 MySQL,所以我的 extensions.ini 中有這二行
extension=pdo.so
extension=pdo_mysql.so

接著在程式中,我們需要宣告 PDO 啟動的功能
代碼: [選擇]

define('DB_NAME','test');
define('DB_USER','test');
define('DB_PASSWD','test');
define('DB_HOST','localhost');
define('DB_TYPE','mysql');
$dbh = new PDO(DB_TYPE.':host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASSWD);


文中的使用常數設定是我個人的習慣,各位不用像我這麼麻煩

當像上面的操作,$dbh 本身就是代表了PDO的連線了

那要怎麼使用PDO呢?

第一式 懶人法 query

什麼都不用想,像平常一樣的使用 query 的函式
代碼: [選擇]

$sql = 'select * from test';
foreach ( $dbh->query($sql) as $value)
{
    echo $value[col];
};


第二式 自動帶入法 prepare

我個人使用PDO後,偏好利用 prepare 的函式來進行作動

prepare 的好處是可以先寫好 SQL 碼,並且在稍後自動帶入我們要的資料
這裡我想最大的好處是比起直接利用 query 可以減少許多安全性的問題

首先,我們利用 prepare 進行 SQL 碼的設定,在利用bindparm 來進行設定的動作
代碼: [選擇]

$sth = $dbh->prepare('update db set zh_CN= :str where SN=:SN');
$sth->bindParam(':str',$str,PDO::PARAM_STR,12);
$sth->bindParam(':SN',$SN);
$sth->execute();


請注意文中的 :str 及 :SN,當我們利用 bindParam的函式,可以利用 :word 來指定系統需要套用的部份,像是我們利用 :str 及 :SN 來指定
而實際的內容,就靠bindParam還可以指定我們要輸入的型態。

首先我們先看 :str 的指定,:str 由於我確定資料是屬於文字,因此利用 PD::PARAM_STR 來告訴程式“這個是字串喲”,並且給一個範圍,也就是長度是12個位元。
我們也可以不要那麼復雜,像 :SN ,雖然也是用 bindParam 來指定,但是我們省略了型態及長度,PHP 會用該變數預設的型態來套用。

最後呢,就是利用 $sth->execute(); 來進行執行的動作。

基本上不難,甚至可以說很簡單呢!

如果你有大量需要重復套用的資料,你就可以拼了命的重新利用 bindParam 來指定,比如我的 :str 及 :SN 如果有十筆資料,我也可以這樣子直接新增到資料庫
代碼: [選擇]

$sth = $dbh->prepare('insert into db ("zh_CN","zh_TW")values(:str , :SN');
foreach ($array => $value )
{
$sth->bindParam(':str',$value[str],PDO::PARAM_STR,12);
$sth->bindParam(':SN',$value[SN]);
$sth->execute();
}

甚至強者如我朋友... 把所有可能的 SQL 全寫在一個檔案裡面,後來的過程SQL的部份就變成全用變數帶進去了!
反正資料可以用現成的方式套用嘛!

那,如果利用 prepare 的方式來 select ,關鍵字當然也可以像上面的方式利用 :word 來指定

代碼: [選擇]

$sth = $dbh->prepare('select * from db where SN = :SN');
$sth->bindParam(':SN',$value[SN]);
$sth->execute();
while($meta = $sth->fetch(PDO::FETCH_ASSOC))
{
echo $meta["name"];
}


這裡新出現的是 fetch,跟mysql_fetch_row() 的意思差不多
但是在 fetch() 中我們發現多了一個 PDO::FETCH_ASSOC 這個東西
fetch() 提供了許多獲取資料的方式,而 PDO::FETCH_ASSOC 指的就是傳回下一筆資料的欄位名及值啦
比如上例,利用 $meta 來取得 fetch 傳回的資料,此時
$meta 的元素名稱就是資料庫的欄位名稱,而內容當然就是值本身

這個跟你利用 mysql_fetch_row() 時不一樣,因為除了欄位名稱,mysql_fetch_row() 還會依照順利
將元素名稱除了欄位外在多給予一個以序號的方式為基礎的元素,那難道 PDO 沒有嗎?
當然有,只要將 PDO::FETCH_ASSOC 改為 PDO::FETCH_BOTH,那用法就跟 mysql_fetch_row() 沒什麼倆樣了。

如何除錯
除錯是所有程式設計師中心中永遠的痛,我們使用 PDO 要如何除錯呢?
其實 PDO 已經提供了二個非常方便的函式
errorInfo() 及 errorCode()
用法也是世界簡單,每當我們利用 execute() 執行後,如果有錯誤
那 errorInfo() 及 errorCode() 中就會有內容
我們就可以這樣子做啦....
代碼: [選擇]

$sth = $dbh->prepare('select * from db where SN = :SN');
$sth->bindParam(':SN',$value[SN]);
$sth->execute();
if ($sth->errorCode())
{
echo "有錯誤!有錯誤!";
print_r($sth->errorInfo());
}


而 $sth->errorInfo() 會是一個陣列,這個陣列有三個值
0 為SQLSTATE error code
1 為你所使用的 Driver 所傳回的錯誤碼
2 為你所使用的 Driver 所傳回的錯誤訊息

好,以上應該足夠應付一般的程式開發了
PDO 一點也不難,對吧!

alishaqoo

  • 懷疑的國中生
  • **
  • 文章數: 47
    • 檢視個人資料
PDO 基本用法
« 回覆 #1 於: 2007-09-14 09:37 »
很棒object喔

說明得很清楚

感謝分享

梁楓

  • 俺是博士!
  • *****
  • 文章數: 6220
    • 檢視個人資料
PDO 基本用法
« 回覆 #2 於: 2007-09-22 15:05 »
今天在不同的Linux 開發一些東西
突然發現...
怎麼東西跟其它系統長相不一樣了...

後來發現...因為這一行

$rowcount = $sub_sth->rowCount() ;

這行,永遠為0

我不確定是不是ubuntu 的問題,至少我在我的FreeBSD 沒有這個狀況

flylinux

  • 訪客
PDO 基本用法
« 回覆 #3 於: 2007-10-18 09:52 »
我在php的站上看到這一句話!
For most databases, PDOStatement->rowCount() does not return the number of rows affected by a SELECT statement. Instead, use PDO->query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement->fetchColumn() to retrieve the number of rows that will be returned. Your application can then perform the correct action
看來好像有的database不支媛select的rowCount()的方法,需改用select count(*)來做!

ricky

  • 區域板主
  • 鑽研的研究生
  • *****
  • 文章數: 669
    • 檢視個人資料
    • Ricky 碎碎唸
PDO 基本用法
« 回覆 #4 於: 2007-10-18 12:38 »
看PDO什麼時候打算修正這個問題吧
感覺PDO進度也是要動不動的
從2006年5月後都沒有動靜了
目前使用上,Postgres是ok
可是sqlite就不行嘍
除非您不會有移轉資料庫的問題
並不建議使用PDO作為專案開發
還是改用adodb這類功能比較完整的方案吧
我的symfony作品:YOMOpets 寵物誌
有興趣可以一起來討論symfony喔
我的部落格:http://ricky.ez2.us/

abbychau

  • 可愛的小學生
  • *
  • 文章數: 4
    • 檢視個人資料
回覆: PDO 基本用法
« 回覆 #5 於: 2010-03-03 20:52 »
和mysqli 比較起來那一個類比較好用呢?

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
回覆: PDO 基本用法
« 回覆 #6 於: 2003-01-01 05:09 »
和mysqli 比較起來那一個類比較好用呢?

訴求上就不一樣了...怎麼比?...

php 5.3 以後還有 mysql-nt 你覺的要不要也抓進來比...?....
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

arayc

  • 可愛的小學生
  • *
  • 文章數: 5
    • 檢視個人資料
回覆: PDO 基本用法
« 回覆 #7 於: 2011-06-17 15:32 »
看起來跟adodb差不多,不過adodb好像比較好用方便