ZetCode

PHP PDOStatement::errorInfo 方法

最后修改于 2025 年 4 月 19 日

PDOStatement::errorInfo 方法检索由 PDOStatement 对象执行的最后一个操作的扩展错误信息。

基本定义

PDOStatement::errorInfo 返回一个数组,其中包含此语句句柄执行的最后一个操作的错误信息。该数组包含三个字段。

语法:public PDOStatement::errorInfo(): array。返回的数组包含 SQLSTATE 错误码、驱动程序特定的错误码和驱动程序特定的错误消息。

基本用法示例

这展示了在 SQL 操作失败后如何使用 errorInfo。

pdo_errorinfo_basic.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $stmt = $pdo->prepare('SELECT * FROM non_existent_table');
    $stmt->execute();
    
    if ($stmt->errorCode() !== '00000') {
        $errorInfo = $stmt->errorInfo();
        echo "SQLSTATE: {$errorInfo[0]}\n";
        echo "Driver Code: {$errorInfo[1]}\n";
        echo "Error Message: {$errorInfo[2]}\n";
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

这会尝试查询一个不存在的表。我们使用 errorInfo 来获取详细的错误信息。数组包含 SQLSTATE、驱动程序代码和错误消息。

准备语句的错误处理

这演示了带有失败的准备语句的 errorInfo。

pdo_errorinfo_prepared.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $stmt = $pdo->prepare('INSERT INTO users (invalid_column) VALUES (?)');
    $stmt->execute(['John Doe']);
    
    if ($stmt->errorCode() !== '00000') {
        $errorInfo = $stmt->errorInfo();
        echo "Error occurred:\n";
        print_r($errorInfo);
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

这会尝试将数据插入一个不存在的列。errorInfo 提供详细的错误信息。数组输出显示了所有三个错误组件。

比较 errorInfo 和 errorCode

这展示了 errorInfo 和 errorCode 方法之间的区别。

pdo_errorinfo_vs_errorcode.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $stmt = $pdo->prepare('SELECT invalid_column FROM users');
    $stmt->execute();
    
    echo "errorCode: " . $stmt->errorCode() . "\n";
    echo "errorInfo:\n";
    print_r($stmt->errorInfo());
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

这比较了简单的错误代码和详细的错误信息。errorCode 只返回 SQLSTATE,而 errorInfo 提供完整的错误详细信息。

事务错误处理

这演示了在事务上下文中如何使用 errorInfo。

pdo_errorinfo_transaction.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $pdo->beginTransaction();
    
    $stmt1 = $pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?');
    $stmt1->execute([100, 1]);
    
    $stmt2 = $pdo->prepare('UPDATE invalid_table SET balance = balance + ? WHERE id = ?');
    $stmt2->execute([100, 2]);
    
    if ($stmt2->errorCode() !== '00000') {
        $errorInfo = $stmt2->errorInfo();
        echo "Transaction failed:\n";
        print_r($errorInfo);
        $pdo->rollBack();
    } else {
        $pdo->commit();
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

这展示了带有 errorInfo 的事务错误处理。由于表无效,第二个语句失败。我们在检查错误后回滚事务。

多语句错误处理

这演示了如何处理来自多个语句的错误。

pdo_errorinfo_multiple.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $statements = [
        'SELECT * FROM users',
        'SELECT * FROM non_existent_table',
        'SELECT invalid_column FROM users'
    ];
    
    foreach ($statements as $sql) {
        $stmt = $pdo->query($sql);
        if ($stmt->errorCode() !== '00000') {
            echo "Error in statement: $sql\n";
            print_r($stmt->errorInfo());
            echo "\n";
        }
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

这会执行多个语句并检查每个语句是否存在错误。对于失败的语句,我们使用 errorInfo 输出 SQL 和错误信息。

不同数据库驱动程序的错误信息

这展示了 errorInfo 在不同数据库驱动程序之间是如何变化的。

pdo_errorinfo_drivers.php
<?php

declare(strict_types=1);

$configs = [
    'mysql' => 'mysql:host=localhost;dbname=testdb',
    'sqlite' => 'sqlite:/path/to/database.sqlite'
];

foreach ($configs as $driver => $dsn) {
    try {
        $pdo = new PDO($dsn, 'user', 'password');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
        
        $stmt = $pdo->prepare('SELECT * FROM non_existent_table');
        $stmt->execute();
        
        echo "Driver: $driver\n";
        print_r($stmt->errorInfo());
        echo "\n";
    } catch (PDOException $e) {
        echo "Connection error ($driver): " . $e->getMessage() . "\n";
    }
}

这比较了 MySQL 和 SQLite 驱动程序的 errorInfo 输出。每个驱动程序可能为相同的错误情况提供不同的错误代码和消息。

自定义错误处理包装器

这创建了一个用于一致错误处理的包装函数。

pdo_errorinfo_wrapper.php
<?php

declare(strict_types=1);

function executeStatement(PDO $pdo, string $sql, array $params = []): array {
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    
    if ($stmt->errorCode() !== '00000') {
        $errorInfo = $stmt->errorInfo();
        return [
            'success' => false,
            'error' => [
                'sqlstate' => $errorInfo[0],
                'code' => $errorInfo[1],
                'message' => $errorInfo[2]
            ]
        ];
    }
    
    return ['success' => true, 'data' => $stmt->fetchAll()];
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $result = executeStatement($pdo, 'SELECT * FROM non_existent_table');
    
    if (!$result['success']) {
        echo "Query failed:\n";
        print_r($result['error']);
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

这创建了一个可重用的函数,用于标准化错误处理。该函数返回一个一致的结构,无论查询是成功还是失败,并使用 errorInfo 进行详细的错误报告。

最佳实践

来源

PHP PDOStatement::errorInfo 文档

本教程涵盖了 PDOStatement::errorInfo 方法,并通过实际示例展示了数据库操作中不同的错误处理场景。

作者

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

列出 所有 PHP PDO 函数