- 資料庫處理時可以包在 try 中,發生問題時可以丟給 catch 處理(或更細部處理)
catch(PDOException $e){},
PDOException 繼承 Exception 可呼叫一般 method,
例如 getCode() 、getMessage() 、getLine() 、getFile() ;
還有等同於 PDO::errorInfo() method 的 errorInfo 「屬性」可用
($e->errorInfo)
errorInfo 為 array,必須用 array 的操作取出。 - 要執行 SQL 指令有三種方式:
$conn->exec() 、$conn->query() 、$conn->prepare() 。
若要快速執行 SQL 指令,可以呼叫 $conn->exec(SQL)。會傳回執行成功的筆數 。
如果 INSERT,通常是 1,若是 DELETE 或 UPDATE 或 SELECT,筆數可能更多。
$conn->exec 較適合用來快速下 INSERT、DELETE、UPDATE 指令(不需回傳資料)。 - 若要快速執行 SELECT 的 SQL 指令取出 ResultSet,
可以呼叫 $conn->query(SQL) 。
會傳回 ResultSet 物件,然後再自行讀出 ResultSet 裡的個別 row 資料。若要用 query() 取出 ResultSet,為了防止 SQL Injection 攻擊產生錯亂,
最好先將 SQL 指令用 $conn->quote(SQL) 處理過。
quote() 會處理引號字串相關事宜;
但是若是要下 INSERT、DELETE、UPDATE 之類的 SQL 指令,
建議最好還是用 $conn->prepare() 來產生 PreparedStatement。 - $conn->prepare(arg1,arg2) 可以執行預儲指令執行增刪修查等四種含變數的 SQL,
arg1(String) :
傳入要執行的 SQL 指令(字串),但是可以設定變數,在執行期才決定變數的值,
變數可以用 :name 或 ? 兩種 placeholder 來代表,
常用於 INSERT 、UPDATE 及 DELETE 等需要多次進行資料處理的 SQL 上;
要注意的是,SQL 中不可將 Column 、Table Name 等用 placeholder 代替,
否則會出現「所給的資料數量與 placeholder 數量不符 」的奇怪錯誤,
不管是 MySQL 或 PostgreSQL 都一樣。arg2(Hash) :
傳入 key=>value 關聯式陣列型態的 Driver 選項。
一般會傳入 array(PDO::ATTR_CURSOR=>PDO::CURSOR_SCROLL) ;
表示使用 scrollable cursor 以任意移動 ResultSet 的 cursor 位置;
如果進行 MANIPULATE 的動作(亦即 INSERT 、UPDATE 、DELETE )時,
本參數設定錯誤的話(例如設定為上例的 PDO::ATTR_CURSOR ),
則 MANIPULATE 的動作將不會成功(不設定反而可以正常運作)。 - $conn->prepare 得到一個 PDOStatement 物件(PreparedStatement),
如果要指定 SQL 中的變數值,可以透過以下三種方式:-
bindParam(param,var,type,length):
param(String) :
指定 SQL 中變數的名稱,
如果是 :name 之類的 placeholder,則直接輸入 :name 「字串 」,
字串前面的 ":" 可以省略,加或不加都可以正常執行。
例如 bindParam(":room",…) 或 bindParam("room",…) 都可以,
":" 放在 SQL 中是為了代表「這是一個 placeholder」;
如果是 ? 之類的 placeholder,則是輸入「數值 」,第一個 ? 是 1。var(&$var) :
指定一個「變數 」的值給此 SQL 中的 placeholder。
一定要指定變數而不能指定 literal 實字,否則會發生錯誤。
若要指定實字,則使用 bindValue() 指定。type(int) :
設定此變數的型態。
數值 型態是 PDO::PARAM_INT ,字串 型態是 PDO::PARAM_STR ,
預設為 PDO::PARAM_STR。可參考 PHP 官網 PDO 說明頁的 Constants。
http://tw2.php.net/manual/en/pdo.constants.php
即使變數型態非此處所設定的型態,還是可以正常傳入 SQL 中。
可能用於 Stored Procedure。length(int) :
設定此變數的長度。即使傳入的變數長度超過此限,資料還是可以正常傳入 SQL。
可能用於 Stored Procedure。一般使用 bindParam() 只需要傳入前兩個引數就可以了。
-
bindValue(param,value,type):
param(String) :
同 bindParam,指定 SQL 中變數的名稱,
如果是 :name 之類的 placeholder,則直接輸入 :name 「字串 」,
字串前面的 ":" 可以省略,加或不加都可以正常執行。
例如 bindValue(":room",…) 或 bindValue("room",…) 都可以,
":" 放在 SQL 中是為了代表「這是一個 placeholder」;
如果是 ? 之類的 placeholder,則是輸入「數值 」,第一個 ? 是 1。value(String or int etc.) :
傳入一個 literal 實字,即使傳入變數也可以,
而 bindParam 第二引數是 by reference (&$var),所以不可以傳入實字。type(int) :
設定此變數的型態。
數值 型態是 PDO::PARAM_INT ,字串 型態是 PDO::PARAM_STR ,
預設為 PDO::PARAM_STR。可以參考 PHP 官網 PDO 說明頁的 Constants。
http://tw2.php.net/manual/en/pdo.constants.php
即使變數型態非此處所設定的型態,還是可以正常傳入 SQL 中。
可能用於 Stored Procedure。 -
設定 array 資料:
如果是 :name 型態的 placeholder,
則建立 array(key=>value) 類的關聯式陣列 ,
如果是 ? 型態的 placeholder,
則建立 array(value,value,..) 類的索引式陣列 ,
關聯式陣列內容可以不照順序,但是索引式陣列必須依照 placeholder 順序放置。
-
- $conn->prepare() 設定 SQL,並指定相對於 placeholder 的值之後,
最後以 $stat->execute() 執行 SQL 指令。
如果資料是以 bindParam() 或 bindValue() 設定,
則 execute() 可以不用傳入引數;
如果將資料包成 array,則把 array 傳入 execute() 中。如果有多項指令要執行,可以將資料放到 array 中(含多項 array 型態內容 的 array),
然後用 foreach 逐項用 bindParam() 或 bindValue() 設定值之後再 execute(),
或將每一個 array 丟入 $stat->execute() 當引數。 - 執行 $stat->execute() ,
如果成功,得到的回傳值是 TRUE;如果失敗,則是 FALSE。
如果執行的是 SELECT 的查詢,則會將查到的資料存入原來的 $stat 中,
不需要另外用一個變數來接收 ResultSet (也不能這麼做)。 - 透過 $stat->prepare() 或 $conn->query(),
執行 SELECT SQL 所得到的 ResultSet,
可以用 fetch() 、fetchAll() 、fetchColumn() 等取出資料
(fetchObject() 用於 ORM)- fetch(style,ori,offset) :用於取出單一筆資料。
style(int) :
決定取出 row 成為哪一種型態。一般常用索引型陣列、關聯式陣列、物件三種。PDO::FETCH_NUM 可以用索引取出欄位資料如 $row[0]、$row[1] … PDO::FETCH_ASSOC 可以用字串取出欄位資料如 $row["room"]、$row["name"] … PDO::FETCH_BOTH 可以用索引或欄位名稱的字串取出欄位資料 PDO::FETCH_OBJ 可以用物件表示法取出資料如 $row->room、$row->name … PDO::FETCH_LAZY 可以用索引、欄位名稱的字串、物件表示法取出資料 以上 BOTH 等於 NUM 和 ASSOC (association) 的合體,
LAZY 等於 BOTH 和 OBJ 的合體。如果用 print_r 將資料 dump 出來,
可以發現 BOTH 會存有兩份相同的資料,只是取用方式不同。若用 style 設定為複合式,則同一筆 row 可以用不同方式取出資料,例如:
print "姓名:{$row['name']},年齡:{$row[1]},電話:".$row->tel;ori(int) :
決定下一筆資料的位置。預設為 PDO::FETCH_ORI_NEXT ,也就是取出下一筆。
如果要讓 cursor 可以任意移動,
則設定為 PDO::FETCH_ORI_ABS (absolute),
或者 PDO::FETCH_ORI_REL ( relative 相對於前一筆),
前面 prepare() 的 arg2 要傳入
array(PDO::ATTR_CURSOR=>PDO::CURSOR_SCROLL)。
可以參考 http://tw2.php.net/manual/en/pdo.constants.php 網址中,
PDO::FETCH_ORI_* 的部份。offset(int) :
如果 prepare() 的 arg2 傳入
array(PDO::ATTR_CURSOR=>PDO::CURSOR_SCROLL) ,
然後第二引數設定為 PDO::FETCH_ORI_ABS 或 PDO::FETCH_ORI_REL ,
則可以設定這一引數以任意移動 cursor ;
如果是 REL 還可以設定為負數 往前移動。如果 Driver 不支援 scrollable cursor(如 mysql pdo 不支援),
則沒有辦法任意移動 cursor 來指定要取出哪一筆 row。(PostgreSQL 支援 ) - fetchAll(style,arg) :用於取出所有 ResultSet 的資料,存成陣列型陣列或物件陣列。
style(int) :
同 fetch() 的第一引數,決定取出 row 成為哪一種型態。
雖然可以設定成複合型態 BOTH 或物件型態 OBJ ,但是沒辦法設定為 LAZY 。
除此之外有個不同於 fetch() 可用的型態 PDO::FETCH_COLUMN ,
設定為 COLUMN 的話,可以將 ResultSet 某一個欄位 的所有資料存成索引式陣列arg(int) :
如果 style 設定為 PDO::FETCH_COLUMN 的話,
此引數可以設定要取出哪一個欄位。
欄位索引從 0 開始,第一欄為 0 。 - fetchColumn(col) :用於取出「下一筆 」資料中某個欄位的值。
col(int) :
指定要取出的欄位編號,欄位索引從 0 開始。如果沒有傳入值,則表示取第一欄。
(fetchColumn() 等同於 fetchColumn(0))
回傳字串形態的資料。如果引數數值超過欄位數範圍,則回傳 null (找不到)。
- fetch(style,ori,offset) :用於取出單一筆資料。
- 只要是透過 PreparedStatement 處理的 INSERT、DELETE、UPDATE、SELECT,
都可以利用 $stat->rowCount() 取得執行成功的筆數
(類似 $conn->exec() 的回傳值)。
(由 $conn->query() 執行 SELECT 取得的 $stat 也可用 rowCount() 得到查詢筆數)
一般資料庫系統都可以透過 rowCount() 得到 INSERT、DELETE、UPDATE 執行成功的筆數,
不過有些資料庫系統不支援 rowCount() 取得 SELECT 的執行結果。
(MySQL 支援 SELECT 的 rowCount(),但是 PostgreSQL 不支援 ) - 如果在 PDO 物件(Connection)操作中發生錯誤(exec()、query()、prepare() 等),
可以呼叫 PDO 物件 的 errorCode() 或 errorInfo() 取得錯誤訊息;
若是在 PDOStatement 物件操作中發生錯誤,
(bindParam()、execute()、fetch() 等)
則可以呼叫 PDOStatement 物件 的 errorCode() 或 errorInfo() 取得錯誤訊息。errorInfo() 回傳一個錯誤訊息堆疊的 array,
也可以在 catch 中用 PDOException->errorInfo 取得。
(為 property 而非 method)。
PDO存取资料库
最新推荐文章于 2022-08-16 19:12:46 发布