ZetCode

PHP PDOException 类

最后修改于 2025 年 4 月 19 日

PHP PDOException 类表示 PDO(PHP 数据对象)引发的错误。它提供了有关数据库操作失败的详细信息。

基本定义

PDOException 扩展了标准的 PHP Exception 类。它增加了特定于数据库的错误信息。这包括 SQLSTATE 错误代码和驱动程序特定代码。

当 PDO 配置为 PDO::ERRMODE_EXCEPTION 时,PDO 会抛出 PDOException。这是现代 PHP 中 PDO 操作推荐的错误处理模式。

连接错误处理

此示例显示了如何使用 PDOException 处理数据库连接错误。

pdo_connection_error.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=wrong_host;dbname=nonexistent_db', 
                  'invalid_user', 'wrong_password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage() . "\n";
    echo "SQLSTATE code: " . $e->getCode() . "\n";
    echo "Driver-specific code: " . $e->errorInfo[1] . "\n";
}

此代码尝试使用无效的凭据进行连接。catch 块处理 PDOException。它显示错误消息、SQLSTATE 代码和驱动程序代码。

查询执行错误

此示例演示了如何处理 SQL 查询执行期间的错误。

pdo_query_error.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Table doesn't exist
    $stmt = $pdo->query('SELECT * FROM nonexistent_table');
} catch (PDOException $e) {
    echo "Query failed: " . $e->getMessage() . "\n";
    print_r($e->errorInfo);
}

此代码尝试查询一个不存在的表。PDOException 通过 getMessage() 和 errorInfo 提供详细的错误信息。errorInfo 包含一个包含错误详细信息的数组。

事务错误处理

此示例显示了如何处理数据库事务中的错误。

pdo_transaction_error.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $pdo->beginTransaction();
    
    // Valid query
    $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");
    
    // Invalid query - will throw exception
    $pdo->exec("UPDATE nonexistent_table SET value = 1");
    
    $pdo->commit();
} catch (PDOException $e) {
    $pdo->rollBack();
    echo "Transaction failed: " . $e->getMessage() . "\n";
    echo "Error code: " . $e->errorInfo[0] . "\n";
}

此示例演示了事务错误处理。第二个查询失败,触发回滚。catch 块显示错误消息和 SQLSTATE 代码。

预处理语句错误

此示例处理预处理语句中的错误。

pdo_prepared_error.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Column doesn't exist
    $stmt = $pdo->prepare('SELECT invalid_column FROM users WHERE id = :id');
    $stmt->execute(['id' => 1]);
    
    $user = $stmt->fetch();
} catch (PDOException $e) {
    echo "Prepared statement error: " . $e->getMessage() . "\n";
    echo "Error info: " . print_r($e->errorInfo, true) . "\n";
}

此代码尝试选择一个不存在的列。PDOException 提供错误详细信息。errorInfo 包含 SQLSTATE、驱动程序代码和错误消息。

自定义异常处理

此示例演示了如何为 PDO 操作创建自定义异常处理程序。

pdo_custom_handler.php
<?php

declare(strict_types=1);

function handlePdoException(PDOException $e): void {
    $errorMsg = "Database Error:\n";
    $errorMsg .= "Message: " . $e->getMessage() . "\n";
    $errorMsg .= "Code: " . $e->getCode() . "\n";
    $errorMsg .= "File: " . $e->getFile() . "\n";
    $errorMsg .= "Line: " . $e->getLine() . "\n";
    
    error_log($errorMsg, 3, 'pdo_errors.log');
    echo "A database error occurred. Please try again later.";
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Invalid query
    $pdo->query('SELECT * FROM nonexistent_table');
} catch (PDOException $e) {
    handlePdoException($e);
}

此代码创建了一个自定义的 PDOException 处理函数。它将详细的错误信息记录到文件中,并显示用户友好的消息。这对于生产环境来说是一个好的实践。

多种异常类型

此示例展示了如何分别处理不同的数据库异常类型。

pdo_multiple_exceptions.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Could be any PDO operation
    $pdo->query('INVALID SQL SYNTAX');
} catch (PDOException $e) {
    switch ($e->errorInfo[0]) {
        case '42S02': // Base table or view not found
            echo "Database table not found. Please contact support.";
            break;
        case '42000': // Syntax error
            echo "SQL syntax error detected.";
            break;
        case 'HY000': // General error
            echo "A general database error occurred.";
            break;
        default:
            echo "An unexpected database error occurred.";
    }
    
    error_log($e->getMessage());
}

此代码以不同的方式处理不同的 SQLSTATE 错误代码。它为表不存在、语法错误和一般错误提供了特定的消息。所有错误都会被记录以进行调试。

错误信息方法

此示例演示了从 PDOException 获取错误信息的各种方法。

pdo_error_methods.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Invalid operation
    $pdo->exec('DROP TABLE nonexistent_table');
} catch (PDOException $e) {
    echo "Standard Exception methods:\n";
    echo "Message: " . $e->getMessage() . "\n";
    echo "Code: " . $e->getCode() . "\n";
    echo "File: " . $e->getFile() . "\n";
    echo "Line: " . $e->getLine() . "\n";
    echo "Trace: " . $e->getTraceAsString() . "\n";
    
    echo "\nPDO-specific methods:\n";
    print_r($e->errorInfo);
}

此示例显示了所有可用的错误信息方法。标准的 Exception 方法提供基本的错误详细信息。PDO 特有的 errorInfo 提供特定于数据库的代码和消息。这对于调试复杂问题很有用。

最佳实践

来源

PHP PDOException 文档

本教程涵盖了 PHP PDOException 类,并通过实际示例演示了如何有效处理各种数据库错误场景。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 PHP PDO 函数