PDO為PHP訪問各類數(shù)據(jù)庫(kù)定義了一個(gè)輕量級(jí)一致性的接口,無(wú)論什么數(shù)據(jù)庫(kù),都可以通過一致的方法執(zhí)行查詢和獲取數(shù)據(jù),而不用考慮不同數(shù)據(jù)庫(kù)之間的差異,大大簡(jiǎn)化了數(shù)據(jù)庫(kù)操作。使用PDO可以支持mysql、postgresql、oracle、mssql等多種數(shù)據(jù)庫(kù)。
本文以基礎(chǔ)講解常用的PHP以PDO方式操作MySQL,包括常用的CURD語(yǔ)句執(zhí)行,以及預(yù)處理語(yǔ)句和事務(wù)的應(yīng)用。雖然很多朋友使用開發(fā)框架封裝好了數(shù)據(jù)庫(kù)操作層,或者使用ORM等不直接接觸SQL語(yǔ)句,但是在一些小項(xiàng)目中可能會(huì)用到原生的數(shù)據(jù)庫(kù)操作,所以雖然是基礎(chǔ)但是很有用。
準(zhǔn)備
我們準(zhǔn)備一張mysql數(shù)據(jù)表mycomments,這是一張常見的評(píng)論表。
連接
首先創(chuàng)建PDO對(duì)象,建立與數(shù)據(jù)庫(kù)服務(wù)器的連接。
PDO::setAttribute()用于設(shè)置屬性,如上面的代碼中就設(shè)置了使用異常模式處理錯(cuò)誤。
查詢
如果我們不使用預(yù)處理語(yǔ)句,可以直接使用query()和exec()方法執(zhí)行sql語(yǔ)句。
而實(shí)際開發(fā)中我們最常用的是預(yù)處理語(yǔ)句,簡(jiǎn)單的說預(yù)處理語(yǔ)句預(yù)先將sql命令分析一次,可以多次執(zhí)行,提高了處理效率,而且能有效防止SQL注入。在執(zhí)行單個(gè)查詢時(shí)快于直接使用query()或exec()的方法,速度快且安全,所以強(qiáng)烈推薦使用預(yù)處理語(yǔ)句。
使用預(yù)處理語(yǔ)句處理時(shí)配套的方法是prepare()和execute()。
我們用預(yù)處理語(yǔ)句來查詢符合條件的數(shù)據(jù)記錄:
我們?cè)趕ql語(yǔ)句中使用問號(hào)(?)參數(shù)作為占位符,使用bindParam()可以設(shè)置綁定參數(shù)值。
不過,如果有很多參數(shù)需要傳遞,我們最常用的是這樣寫:
在execute()方法中加入?yún)?shù)占位符數(shù)組,不使用?占位符可能更直觀點(diǎn)。
fetch()返回查詢結(jié)果中的一行數(shù)據(jù),數(shù)據(jù)以數(shù)組形式返回,該方法可以帶參數(shù),其中參數(shù)默認(rèn)為 PDO::FETCH_BOTH,即返回一個(gè)索引為結(jié)果集列名和以0開始的列號(hào)的數(shù)組,而常用的參數(shù)PDO::FETCH_ASSOC則返回一個(gè)索引為結(jié)果集列名的數(shù)組。
fetchAll()可以獲取結(jié)果集中的所有行,并賦給返回的二維數(shù)組。和fetch()一樣也可以帶參數(shù)。
如查詢表中用戶id為2的所有數(shù)據(jù),可能會(huì)有多行結(jié)果:
打印$row結(jié)果看下,是不是一個(gè)二維數(shù)組?
插入
最常用的插入數(shù)據(jù)表的寫法,如果有自增長(zhǎng)id(一般必須有),使用lastInsertId()可以獲取到插入成功后的id。
更新
使用預(yù)處理更新數(shù)據(jù),rowCount()返回影響行數(shù),大于0即表示執(zhí)行成功的記錄數(shù)。
刪除
對(duì)于只有一個(gè)參數(shù)需要綁定的,可以使用問號(hào)?占位符。刪除后同樣使用rowCount()返回影響行數(shù),大于0表示執(zhí)行成功。
事務(wù)
事務(wù)是確保數(shù)據(jù)庫(kù)一致的機(jī)制,是一個(gè)或一系列的查詢,作為一個(gè)單元的一組有序的數(shù)據(jù)庫(kù)操作。如果組中的所有SQL語(yǔ)句都操作成功,則認(rèn)為事務(wù)成功,事務(wù)則被提交。如果在事務(wù)的組中只有一個(gè)環(huán)節(jié)操作失敗,事務(wù)也不成功,則整個(gè)事務(wù)將被回滾,該事務(wù)中所有操作都被取消。事務(wù)在開發(fā)中也經(jīng)常用到,因?yàn)楹芏鄻I(yè)務(wù)過程都包括多個(gè)步驟,如果任何一個(gè)步驟失敗,則所有步驟都不應(yīng)發(fā)生。
值得注意的是,如果要用到事務(wù)處理功能,你的MySQL應(yīng)該使用InnoDB引擎或者其他支持事務(wù)的引擎,切不可以使用MyISAM引擎。
來看PDO事務(wù)處理實(shí)例:
上述代碼中首先是啟動(dòng)一個(gè)事務(wù),然后依次執(zhí)行三條sql,然后提交事務(wù)。細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn),在第2條sql中查詢條件sid=2有誤,因?yàn)槲覀冊(cè)谇懊鎰?chuàng)建mycomments表的時(shí)候沒有sid這個(gè)字段,所以在執(zhí)行到第2條sql時(shí)就會(huì)出錯(cuò),這個(gè)時(shí)候會(huì)拋出異常,使用try{}cache(){}語(yǔ)句即可捕獲異常,于是就執(zhí)行了回滾事務(wù)rollBack(),而并沒有提交事務(wù)。換句話說就是上面的代碼雖然第一條sql執(zhí)行完了,但是最終執(zhí)行不成功,數(shù)據(jù)庫(kù)沒有任何寫入和更新。