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 函数。