學習PDO中的錯誤與錯誤處理模式

在 PDO 的學習過程當中,咱們常常會在使用事務的時候加上 try...catch 來進行事務的回滾操做,可是你們有沒有注意到默認狀況下 PDO 是如何處理錯誤語句致使的數據庫操做失敗問題呢?今天,咱們就來學習一下。php

PDO 中的錯誤與錯誤處理模式簡介

PDO 提供了三種不一樣的錯誤處理方式:mysql

  • PDO::ERRMODE_SILENT,這是 PDO 默認的處理方式,只是簡單地設置錯誤碼,能夠使用 PDO::errorCode() 和 PDO::errorInfo() 方法來檢查語句和數據庫對象git

  • PDO::ERRMODE_WARNING,除設置錯誤碼以外,PDO 還將發出一條傳統的 E_WARNING 信息。若是隻是想看看發生了什麼問題且不中斷應用程序的流程,那麼此設置在調試/測試期間很是有用。github

  • PDO::ERRMODE_EXCEPTION,除設置錯誤碼以外,PDO 還將拋出一個 PDOException 異常類並設置它的屬性來反射錯誤碼和錯誤信息。面試

原來默認狀況下,咱們的 PDO 是不會處理錯誤信息的,這個你知道嗎?若是不信的話,咱們繼續向下看具體的測試狀況。不過,首先咱們要說明的是,PDO 的錯誤處理機制針對的是 PDO 對象中的數據操做能力,若是在實例化 PDO 對象的時候就產生了錯誤,好比數據庫鏈接信息不對,那麼直接就會拋出異常。( PHP5 中會直接返回一個 NULL,PHP7會拋出異常! )sql

$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 在默認狀況下的錯誤處理機制。其實,這樣的處理並很差,由於若是咱們忘記設置錯誤處理機制的話,就會致使一些錯誤沒法呈現,並且並很差調試。ide

設置爲警告

$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

===============

關注公衆號:【硬核項目經理】

相關文章
相關標籤/搜索