2024 年 PHP 日本大会

PDOException 类

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

简介

表示由 PDO 引发的错误。您不应从自己的代码中抛出PDOException。有关 PHP 中异常的更多信息,请参见异常

类概要

class PDOException extends RuntimeException {
/* 属性 */
protected int|string $code;
public ?array $errorInfo = null;
/* 继承的属性 */
protected string $message = "";
private string $string = "";
protected int $code;
protected string $file = "";
protected int $line;
private array $trace = [];
private ?Throwable $previous = null;
/* 继承的方法 */
public Exception::__construct(string $message = "", int $code = 0, ?Throwable $previous = null)
final public Exception::getCode(): int
final public Exception::getFile(): string
final public Exception::getLine(): int
final public Exception::getTrace(): array
}

属性

errorInfo

对应于PDO::errorInfo()PDOStatement::errorInfo()

code

SQLSTATE 错误代码。使用Exception::getCode()访问它。

添加注释

用户贡献的注释 3 条注释

Typer85 at gmail dot com
14 年前
关于 PDOException,这里有一些有趣的内容,它涉及到与 PHP 动态特性相关的一些烦人的问题。

PDOException 继承自 RuntimeException,后者又继承自 Exception。因此,它可以访问 $code 受保护的类变量,该变量表示异常代码为整数(当然!),并且可以使用 Exception::getCode 方法从外部访问。

有趣的部分在这里。PDOException 实际上将 $code 重新定义为字符串而不是整数,因为在其情况下,$code 实际上包含异常的 SQL 状态,它由字符和数字组成。

手册中实际上已经说明了 $code 是字符串而不是整数,但这可能并不立即清楚,因为它被 PDOException::getCode 被记录为返回整数而不是字符串这一事实所掩盖!

一些开发人员喜欢捕获 PDOException 并将其重新抛出为不同的异常,如果他们将数据库调用包装在外部库中。例如,考虑以下代码

<?php

try {
$PDO = new PDO( '...' ); // PDO 驱动程序 DSN。抛出 PDOException。
}
catch(
PDOException $Exception ) {
// PHP 致命错误。第二个参数必须是整数,但 PDOException::getCode 返回一个
// 字符串。
throw new MyDatabaseException( $Exception->getMessage( ) , $Exception->getCode( ) );
}

?>

请注意,您必须在将 PDOException::getCode 返回的值作为参数传递给异常的构造函数之前,将其类型转换为整数。以下代码将有效

<?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类型,而是直接在自定义异常对象上设置message和code属性。

<?php

class CustomException extends PDOException {

/**
* 重写构造函数并设置message和code属性。
* 解决PHP BUG #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] Access denied for user 'user'@'example.com' (using password: YES)”

使用我的扩展异常类提供

代码:“28000”
消息:“Access denied for user 'user'@'example.com' (using password: YES)”

<?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(); // 输出:“Access denied for user 'user'@'example.com' (using password: YES)”
?>

如果您决定使用此代码,请注意错误代码是字符串(与PHP标准错误(为整数)相反),因为某些错误代码是字母数字的。
To Top