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