PHP Conference Japan 2024

PDOException 類別

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

簡介

表示 PDO 引發的錯誤。您不應該在自己的程式碼中拋出 PDOException。有關 PHP 中例外的更多資訊,請參閱 例外

類別概要

class PDOException extends RuntimeException {
/* 屬性 */
公開 ?陣列 $errorInfo = null;
/* 繼承的屬性 */
保護 字串 $message = "";
私有 字串 $string = "";
保護 整數 $code;
保護 字串 $file = "";
保護 整數 $line;
私有 陣列 $trace = [];
私有 ?可拋出物件 $previous = null;
/* 繼承的方法 */
公開 Exception::__construct(字串 $message = "", 整數 $code = 0, ?可拋出物件 $previous = null)
最終 公開 Exception::getMessage(): 字串
最終 公開 Exception::getCode(): 整數
最終 公開 Exception::getFile(): 字串
最終 公開 Exception::getLine(): 整數
最終 公開 Exception::getTrace(): 陣列
}

屬性

errorInfo

對應於 PDO::errorInfo()PDOStatement::errorInfo()

code

SQLSTATE 錯誤碼。使用 Exception::getCode() 來存取它。

新增註釋

使用者貢獻的註釋 3 則註釋

Typer85 at gmail dot com
14 年前
關於 PDOException,有一些有趣的事情,它涉及到一些與 PHP 動態特性相關的惱人問題。

PDOException 繼承自 RuntimeException,而 RuntimeException 又繼承自 Exception。因此,它可以存取受保護的類別變數 $code,它以整數表示 Exception 的程式碼(很明顯!),並且可以使用 Exception::getCode 方法從外部存取。

有趣的部分來了。PDOException 實際上將 $code 重新定義為字串而不是整數,因為就其情況而言,$code 實際上包含 Exception 的 SQL 狀態,它由字元和數字組成。

文件中實際上記錄了 $code 是一個字串而不是整數,但它可能不是很清楚,因為它被 PDOException::getCode 被記錄為返回整數而不是字串的事實所掩蓋!

一些開發人員喜歡捕捉 PDOException 並將其重新拋出為不同的 Exception,如果他們將資料庫呼叫包裝在外部程式庫中。例如,請考慮以下程式碼

<?php

try {
$PDO = new PDO( '...' ); // PDO 驅動程式 DSN。拋出 PDOException。
}
catch(
PDOException $Exception ) {
// PHP 致命錯誤。第二個參數必須是整數,但 PDOException::getCode 返回字串。
//
throw new MyDatabaseException( $Exception->getMessage( ) , $Exception->getCode( ) );
}

?>

請注意,您必須在將 PDOException::getCode 返回的值作為參數傳遞給 Exception 的建構函式之前,將其型別轉換為整數。以下程式碼可以正常運作

<?php

try {
$PDO = new PDO( '...' ); // PDO 驅動程式 DSN。會拋出 PDOException 例外。
}
catch(
PDOException $Exception ) {
// 注意型別轉換為整數!
throw new MyDatabaseException( $Exception->getMessage( ) , (int)$Exception->getCode( ) );
}

?>

希望這可以為開發人員省下一些原本愉快工作中令人沮喪的時間 :)

祝好運,
radu.potop at wooptoo.com
10 年前
由於 PDOException 將錯誤碼作為字串返回,如果您希望將 PDOException 重新拋出為自訂例外,則需要像下面這樣的建構函式。
此建構函式不會呼叫 parent::__construct,這會強制錯誤碼為 int 類型,而是直接在自訂例外物件上設定訊息和程式碼作為屬性。

<?php

class CustomException extends PDOException {

/**
* 覆寫建構函式並設定訊息和程式碼屬性。
* 解決 PHP 錯誤 #51742, #39615
*/
public function __construct($message=null, $code=null) {
$this->message = $message;
$this->code = $code;
}

}
samuelelliot+php dot net at gmail dot com
14 年前
PDOException 有兩個方法可以擷取有關錯誤的資訊。在解釋 PDOException 時,我遇到一個問題,getCode() 提供的錯誤碼沒有意義。我想出了一種方法,可以讓錯誤碼和訊息都更有用。

錯誤的使用者名稱或密碼通常會提供以下資訊

程式碼:0
訊息:「SQLSTATE[28000] [1045] 使用者 'user'@'example.com' 的存取被拒絕(使用密碼:是)」

使用我的擴充例外類別會提供

程式碼:「28000」
訊息:「使用者 'user'@'example.com' 的存取被拒絕(使用密碼:是)」

<?php
class pdoDbException extends PDOException {

public function
__construct(PDOException $e) {
if(
strstr($e->getMessage(), 'SQLSTATE[')) {
preg_match('/SQLSTATE\[(\w+)\] \[(\w+)\] (.*)/', $e->getMessage(), $matches);
$this->code = ($matches[1] == 'HT000' ? $matches[2] : $matches[1]);
$this->message = $matches[3];
}
}
}
?>

這個方法的流程如下:首先檢查訊息開頭是否包含 SQLSTATE 文字。如果存在,則解析訊息以提取 ANSI 碼、SQL 特定碼和訊息內容。解析後的值會儲存在各自的變數中。錯誤碼變數會儲存 ANSI 碼,除非 ANSI 碼為 'HT000'(未映射的錯誤碼),則會使用 SQL 特定碼。

使用這個類別很簡單;與 PDO 互動時,使用 try-catch 區塊,如下所示:

<?php
try {
$pdo = new PDO($dns, $username, $password, $options);
} catch (
PDOException $e) {
throw new
pdoDbException($e);
}
?>

現在您可以使用一般的錯誤方法來取得真正的錯誤碼和訊息。

<?php
echo $err->getCode(); // 輸出: "28000"
echo $err->getMessage(); // 輸出: "使用者 'user'@'example.com' 的存取被拒絕 (使用密碼:是)"
?>

如果您決定使用此程式碼,請注意錯誤碼是一個字串(與 PHP 標準錯誤是整數相反),因為某些錯誤碼是字母數字混合的。
To Top