PHP PDOStatement::errorInfo 方法
最后修改于 2025 年 4 月 19 日
PDOStatement::errorInfo 方法检索由 PDOStatement 对象执行的最后一个操作的扩展错误信息。
基本定义
PDOStatement::errorInfo 返回一个数组,其中包含此语句句柄执行的最后一个操作的错误信息。该数组包含三个字段。
语法:public PDOStatement::errorInfo(): array
。返回的数组包含 SQLSTATE 错误码、驱动程序特定的错误码和驱动程序特定的错误消息。
基本用法示例
这展示了在 SQL 操作失败后如何使用 errorInfo。
<?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。
<?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 方法之间的区别。
<?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。
<?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 的事务错误处理。由于表无效,第二个语句失败。我们在检查错误后回滚事务。
多语句错误处理
这演示了如何处理来自多个语句的错误。
<?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 在不同数据库驱动程序之间是如何变化的。
<?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 输出。每个驱动程序可能为相同的错误情况提供不同的错误代码和消息。
自定义错误处理包装器
这创建了一个用于一致错误处理的包装函数。
<?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 进行详细的错误报告。
最佳实践
- 先检查 errorCode:在调用 errorInfo 之前,请验证是否发生了错误。
- 记录完整的错误信息:存储 errorInfo 的所有三个部分以进行调试。
- 一致使用:在整个过程中应用相同的错误处理模式。
- 与异常结合使用:将 errorInfo 与异常处理结合使用。
- 记录错误代码:维护常见错误代码的文档。
来源
PHP PDOStatement::errorInfo 文档
本教程涵盖了 PDOStatement::errorInfo 方法,并通过实际示例展示了数据库操作中不同的错误处理场景。
作者
列出 所有 PHP PDO 函数。