在 PDO 的學習程序中,我們經常會在使用事務的時候加上 try...catch 來進行事務的回滾操作,但是大家有沒有注意到默認情況下 PDO 是如何處理錯誤陳述句導致的資料庫操作失敗問題呢?今天,我們就來學習一下,
PDO 中的錯誤與錯誤處理模式簡介
PDO 提供了三種不同的錯誤處理方式:
-
PDO::ERRMODE_SILENT,這是 PDO 默認的處理方式,只是簡單地設定錯誤碼,可以使用 PDO::errorCode() 和 PDO::errorInfo() 方法來檢查陳述句和資料庫物件
-
PDO::ERRMODE_WARNING,除設定錯誤碼之外,PDO 還將發出一條傳統的 E_WARNING 資訊,如果只是想看看發生了什么問題且不中斷應用程式的流程,那么此設定在除錯/測驗期間非常有用,
-
PDO::ERRMODE_EXCEPTION,除設定錯誤碼之外,PDO 還將拋出一個 PDOException 例外類并設定它的屬性來反射錯誤碼和錯誤資訊,
原來默認情況下,我們的 PDO 是不會處理錯誤資訊的,這個你知道嗎?如果不信的話,我們繼續向下看具體的測驗情況,不過,首先我們要說明的是,PDO 的錯誤處理機制針對的是 PDO 物件中的資料操作能力,如果在實體化 PDO 物件的時候就產生了錯誤,比如資料庫連接資訊不對,那么直接就會拋出例外,( PHP5 中會直接回傳一個 NULL,PHP7會拋出例外! )
$pdo = new PDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test1', 'root', '');
// Fatal error: Uncaught PDOException: SQLSTATE[HY000] [1049] Unknown database 'blog_test1'
blog_test1 表并不存在,所以在 new PDO 的時候就已經直接會拋出例外了,這個在實體化連接資料庫程序中的錯誤處理機制是固定的,不是我們能修改的錯誤處理機制,畢竟如果連資料庫連接都無法建立的話,就不用談后面的任何操作了,
默認情況
$pdo = new PDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test', 'root', '');
$pdo->query('select * from aabbcc');
var_dump($pdo->errorCode());
// string(5) "42S02"
var_dump($pdo->errorInfo());
// array(3) {
// [0]=>
// string(5) "42S02"
// [1]=>
// int(1146)
// [2]=>
// string(38) "Table 'blog_test.aabbcc' doesn't exist"
// }
在上面的測驗代碼中,我們查詢了 aabbcc 這個表,但其實資料庫中并不存在這個表,如果不使用 errorCode() 或者 errorInfo() 的話,這段代碼不會有任何輸出,也就是說,不會有任何錯誤資訊讓你看到,代碼就直接運行過去了,
這個就是 PDO 在默認情況下的錯誤處理機制,其實,這樣的處理并不好,因為如果我們忘記設定錯誤處理機制的話,就會導致一些錯誤無法呈現,而且并不好除錯,
設定為警告
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$pdo->query('select * from aabbcc');
// Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.aabbcc' doesn't exist
在設定錯誤處理機制為警告后,PDO 會拋出一個不影響程式執行的 warning 資訊,但是,如果我們修改了 ini 檔案中錯誤處理機制后,也可能是看不到警告資訊的,不過相對于默認處理的情況來說,有一條警告資訊已經非常好了,
設定為例外
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->query('select * from aabbcc');
// Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.aabbcc' doesn't exist
最后,我們將錯誤處理機制設定為拋出例外,總算是能讓程式中止運行并且報出 Fatal error 錯誤了,同時,這個例外資訊也是可以通過 try...catch 來捕獲到的,這樣的開發才是我們最需要的開發形式,
屬性添加方式
在上述測驗代碼中,我們使用的是 setAttribute() 方法來設定 PDO 的錯誤處理屬性,但其實我們可以在實體化 PDO 類時就指定一些需要的屬性,
$pdo = new PDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test', 'root', '', [PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING]);
$pdo->query('select * from aabbcc');
// Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.aabbcc' doesn't exist
總結
PDO 已經是現在的主流資料庫連接擴展,也是各種框架的必備連庫擴展,但是如果不深入的學習的話,很多人可能還真不知道很多關于 PDO 的一些知識,框架在為我們帶來便利的同時,也讓我們變得更“笨”,所以,學習還是要更多地接觸底層地知識,免得在面試的時候需要手寫代碼的時候手足無措,
測驗代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/%E5%AD%A6%E4%B9%A0PDO%E4%B8%AD%E7%9A%84%E9%94%99%E8%AF%AF%E4%B8%8E%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86%E6%A8%A1%E5%BC%8F.php
參考檔案:
https://www.php.net/manual/zh/pdo.error-handling.php
===============
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285581.html
標籤:PHP
下一篇:PDO操作大資料物件
