從 PHP 5.1 開始附帶瞭 PDO,PHP 數據對象 (PDO) 擴展為PHP訪問伺服器定義瞭一個輕量級的一致接口。PDO 提供瞭一個 數據訪問 抽象層,這意味著,不管使用哪種伺服器(比如mysql,oracle,mssql…),都可以用相同的函數(方法)來查詢和獲取數據。
1.創建PDO對象
使用PDO擴展必須在php.ini文件中打開相應的擴展,下圖打開瞭pdo_mysql的擴展:
那怎麼創建一個pdo對象呢?
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
//輸出: object(PDO)#1 (0) { }, 拿到pdo對象表示連接成功瞭
var_dump($dbh);
2.PDO對象主要方法
PDO::beginTransaction — 啟動一個事務 PDO::commit — 提交一個事務 PDO::__construct — 創建一個表示伺服器連接的 PDO 實例 PDO::errorCode — 獲取跟伺服器句柄上一次操作相關的 PDO::errorInfo — 獲取最後操作關聯的錯誤信息,返回一個數組 PDO::exec — 執行一條 SQL 語句(insert ,delete,update),並返回受影響的行數,失敗則為false PDO::getAttribute — 取回一個伺服器連接的屬性 PDO::getAvailableDrivers — 返回一個可用驅動的數組 PDO::inTransaction — 檢查是否在一個事務內 PDO::lastInsertId — 返回最後插入行的ID或序列值 PDO::prepare — 預處理語句返回一個PDOStatement 對象 PDO::query — 執行查詢語句,返回一個結果集對象PDOStatement PDO::quote — 給字符串加引號,如:’string’ 用於查詢 PDO::rollBack — 回滾一個事務 PDO::setAttribute — 設置屬性
更多詳見:
3.PDOStatement對象主要方法
在拿到PDO對象後,執行sql語句:
$sql = "select * from product";
$stmt = $dbh -> query($sql);
上述代碼的 $stmt 就是PDOStatement對象,它是執行sql語句後返回的結果集。
PDOStatement對象主要方法:
1. PDOStatement::bindColumn — 綁定一列到一個 PHP 變量
2. PDOStatement::bindParam — 綁定一個參數到指定的變量名
3. PDOStatement::bindValue — 把一個值綁定到一個參數
4. PDOStatement::closeCursor — 關閉遊標,使語句能再次被執行。
5. PDOStatement::columnCount — 返回結果集中的列數
6. PDOStatement::debugDumpParams — 打印一條 SQL 預處理命令
7. PDOStatement::errorCode — 獲取跟上一次語句句柄操作相關的 SQLSTATE
8. PDOStatement::errorInfo — 獲取跟上一次語句句柄操作相關的擴展錯誤信息
9. PDOStatement::execute — 執行一條預處理語句
10. PDOStatement::fetch — 從結果集中獲取下一行
11. PDOStatement::fetchAll — 返回一個包含結果集中所有行的數組
12. PDOStatement::fetchColumn — 從結果集中的下一行返回單獨的一列。
13. PDOStatement::fetchObject — 獲取下一行並作為一個對象返回。
14. PDOStatement::getAttribute — 檢索一個語句屬性
15. PDOStatement::getColumnMeta — 返回結果集中一列的元數據
16. PDOStatement::nextRowset — 在一個多行集語句句柄中推進到下一個行集
17. PDOStatement::rowCount — 返回受上一個 SQL 語句影響的行數
18. PDOStatement::setAttribute — 設置一個語句屬性
19. PDOStatement::setFetchMode — 為語句設置默認的獲取模式。
4.使用PDO操作mysql
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$sql = "update product set price = 1998 where pro_id = 1";
#執行更新語句
$result = $dbh->exec($sql);
if($result){
echo "執行成功,受此語句影響的行數=".$result;
}else{
echo "
錯誤碼:". $dbh->errorCode();
echo "
"; var_dump( $dbh->errorInfo()); } ?>
運行結果:
現在故意把sql寫錯:
$sql = “update productxx set price = 1998 where pro_id = 1”;
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
//故意寫錯sql--------------------
$sql = "update productxx set price = 1998 where pro_id = 1";
$result = $dbh->exec($sql);
if($result){
echo "執行成功,受此語句影響的行數=".$result;
}else{
echo "
錯誤碼:". $dbh->errorCode();
echo "
"; var_dump( $dbh->errorInfo()); } ?>
運行結果:
使用事務:
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$dbh->beginTransaction();//開啟事務
$sql = "update product set price = 1998 where pro_id = 1";
$result = $dbh->exec($sql);
$intrans = $dbh->inTransaction();
var_dump($intrans);//bool(true)
if($result !== false){
$dbh->commit();//事務提交
}else{
$dbh->rollBack();//事務回滾
echo "
錯誤碼:". $dbh->errorCode();
echo "
"; var_dump( $dbh->errorInfo()); } $intrans = $dbh->inTransaction(); var_dump($intrans);//bool(false) ?>
獲取不同形式的結果集:
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$sql = "select pro_id,pinpai from product";
$stmt = $dbh->query($sql);
//返回的結果以字段名為key
$row = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($row);
echo '
'; //返回的結果以數字下標為key $row = $stmt->fetch(PDO::FETCH_NUM); print_r($row); echo '
'; //PDO::FETCH_ASSOC + PDO::FETCH_NUM $row = $stmt->fetch(PDO::FETCH_BOTH);//默認就是PDO::FETCH_BOTH print_r($row); echo '
'; //返回結果是內置標準類stdClass ,伺服器字段名作為屬性名 $row = $stmt->fetch(PDO::FETCH_OBJ);//默認就是PDO::FETCH_BOTH print_r($row); echo '
'; class Row{} //返回結果是指定類對象 ,伺服器字段名作為屬性名 $stmt->setFetchMode(PDO::FETCH_CLASS,'Row'); $row = $stmt->fetch();//默認就是PDO::FETCH_BOTH print_r($row); echo '
'; //獲取所有的結果集 $sql = "select pro_id,pinpai from product limit 2"; $stmt = $dbh->query($sql); //這裡得到的結果是二維數組 $rows = $stmt->fetchAll();//fetchAll([PDO::FETCH_BOTH]) 默認是PDO::FETCH_BOTH echo "
";
print_r($rows);
?>
5.PDO錯誤處理方式
PDO 提供瞭三種不同的錯誤處理模式,以滿足不同風格的應用開發:
1.PDO::ERRMODE_SILENT
此為默認模式。 PDO 將隻簡單地設置錯誤碼,可使用 PDO::errorCode() 和 PDO::errorInfo() 方法來檢查語句和伺服器對象。如果錯誤是由於對語句對象的調用而產生的,那麼可以調用那個對象的 PDOStatement::errorCode() 或 PDOStatement::errorInfo() 方法。如果錯誤是由於調用伺服器對象而產生的,那麼可以在伺服器對象上調用上述兩個方法。
2.PDO::ERRMODE_WARNING
除設置錯誤碼之外,PDO 還將發出一條傳統的 E_WARNING 信息。如果隻是想看看發生瞭什麼問題且不中斷應用程式的流程,那麼此設置在調試/測試期間非常有用。
3.PDO::ERRMODE_EXCEPTION
除設置錯誤碼之外,PDO 還將拋出一個 PDOException 異常類並設置它的屬性來反射錯誤碼和錯誤信息。此設置在調試期間也非常有用,因為它會有效地放大腳本中產生錯誤的點,從而可以非常快速地指出代碼中有問題的潛在區域(記住:如果異常導致腳本終止,則事務被自動回滾)。
異常模式另一個非常有用的是,相比傳統 PHP 風格的警告,可以更清晰地構建自己的錯誤處理,而且比起靜默模式和顯式地檢查每種伺服器調用的返回值,異常模式需要的代碼/嵌套更少。
#pdo設置異常模式
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
註意:不管當前是否設置瞭 PDO::ATTR_ERRMODE ,如果連接失敗, PDO::__construct() 將總是拋出一個 PDOException 異常。未捕獲異常是致命的。
PDO錯誤靜默模式: PDO :: ERRMODE_SILENT
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_SILENT );
//這是一句錯誤的sql
$sql = "select pro_id,pinpai from productxxxx";
$stmt = $dbh->query($sql);
if(!$stmt){
$errArray = $dbh->errorInfo();
var_dump($errArray);
}
?>
PDO錯誤警告模式: PDO :: ERRMODE_WARNING
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_WARNING );
//這是一句錯誤的sql
$sql = "select pro_id,pinpai from productxxxx";
$stmt = $dbh->query($sql);
PDO錯誤異常模式: PDO :: ERRMODE_EXCEPTION
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//這是一句錯誤的sql
$sql = "select pro_id,pinpai from productxxxx";
try {
$stmt = $dbh->query($sql);
} catch (PDOException $e) {
echo $e->getMessage();
}
6.PDO預處理語句
預處理的意思是先提交sql語句到mysql服務端,執行預編譯,客戶端執行多條結構相同的sql語句時,隻需上傳輸入參數即可,這點和存儲過程有點相似。
有兩種語法形式:
#問號占位符形式
select pro_id,pinpai from product WHERE protype_id > ? and pinpai = ?;
#命名占位符形式
select pro_id,pinpai from product WHERE protype_id > :v1 and pinpai = :v2;
1.問號占位符代碼如下:
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
$sql = "select pro_id,pinpai from product WHERE pro_id > ? and pinpai = ?";
try {
$stmt = $dbh->prepare($sql);
//給占位符賦值形式1
$stmt->bindValue(1, 5);
$stmt->bindValue(2, '索尼');
$stmt->execute();
$resultSet = $stmt->fetchAll();
$stmt->closeCursor();
print_r($resultSet);
echo "
"; //給占位符賦值形式2 $stmt->execute(array(3,'索尼')); $resultSet = $stmt->fetchAll(); print_r($resultSet); } catch (PDOException $e) { echo $e->getMessage(); } ?>
2.命名占位符代碼如下:
'set names utf8');//可選參數
$username = "root";//用戶名
$passwd = "root";//密碼
try {
$dbh = new PDO($dsn, $username, $passwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
$sql = "select pro_id,pinpai from product WHERE pro_id > :v1 and pinpai = :v2";
try {
$stmt = $dbh->prepare($sql);
//給占位符賦值形式1
$stmt->bindValue(":v1", 5);
$stmt->bindValue(":v2", '索尼');
$stmt->execute();
$resultSet = $stmt->fetchAll();
$stmt->closeCursor();
print_r($resultSet);
echo "
"; //給占位符賦值形式2 $stmt->execute(array(":v1"=>3,":v2"=>'索尼')); $resultSet = $stmt->fetchAll(); print_r($resultSet); } catch (PDOException $e) { echo $e->getMessage(); } ?>