實在睡不著...痛苦啊...
不過睡不著的時候,最好的方式就是做一些想讓人睡覺的事...
那,就來分享一篇吧...
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 一點也不難,對吧!