ZetCode

PHP PDOStatement::errorCode 方法

最后修改于 2025 年 4 月 19 日

PDOStatement::errorCode 方法检索语句句柄上最后一次操作的 SQLSTATE 错误代码。它有助于错误处理。

基本定义

PDOStatement::errorCode 返回一个五字符的 SQLSTATE 代码。此代码标识最后一次操作期间发生的错误的类型。

值为 '00000' 表示没有发生错误。其他值表示不同类型的错误。该方法不需要参数,并返回一个字符串。

基本的 errorCode 用法

此示例展示了在语句失败后使用 errorCode 的最简单方法。

pdo_errorcode_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();
    
    $errorCode = $stmt->errorCode();
    if ($errorCode !== '00000') {
        echo "Error occurred: $errorCode";
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

此代码尝试查询一个不存在的表。我们将 ERRMODE_SILENT 设置为防止异常。errorCode 方法捕获 SQLSTATE 错误代码。

带无效查询的 errorCode

此示例演示了执行具有无效语法的查询时 errorCode 的用法。

pdo_errorcode_syntax.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('SELEC * FROM users'); // Invalid SQL
    $stmt->execute();
    
    $errorCode = $stmt->errorCode();
    if ($errorCode !== '00000') {
        echo "SQL Error: $errorCode";
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

SQL 语句包含语法错误(SELEC 而不是 SELECT)。errorCode 返回此语法错误的特定 SQLSTATE 代码。

带参数绑定的 errorCode

此示例显示了在参数绑定失败时 errorCode 的用法。

pdo_errorcode_binding.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 (name, email) VALUES (?, ?)');
    $stmt->bindValue(1, 'John Doe');
    // Intentionally skip binding the second parameter
    
    $stmt->execute();
    
    $errorCode = $stmt->errorCode();
    if ($errorCode !== '00000') {
        echo "Binding Error: $errorCode";
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

我们故意跳过第二个参数的绑定,以演示 errorCode 如何捕获参数绑定错误。SQLSTATE 代码将指示缺少参数。

带事务的 errorCode

此示例显示了在事务中发生约束失败时 errorCode 的用法。

pdo_errorcode_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();
    
    // First insert succeeds
    $stmt1 = $pdo->prepare('INSERT INTO users (id, name) VALUES (?, ?)');
    $stmt1->execute([1, 'John']);
    
    // Second insert fails due to duplicate ID
    $stmt2 = $pdo->prepare('INSERT INTO users (id, name) VALUES (?, ?)');
    $stmt2->execute([1, 'Jane']);
    
    $errorCode = $stmt2->errorCode();
    if ($errorCode !== '00000') {
        echo "Duplicate entry error: $errorCode";
        $pdo->rollBack();
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

第二次插入违反了主键约束。errorCode 捕获此特定错误,允许我们在代码中适当地处理它。

不同数据库系统的 errorCode

此示例演示了 SQLite 与 MySQL 在 errorCode 行为上的差异。

pdo_errorcode_multidb.php
<?php

declare(strict_types=1);

// MySQL example
try {
    $mysql = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $mysql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $stmt = $mysql->prepare('SELECT * FROM non_existent_table');
    $stmt->execute();
    
    echo "MySQL error code: " . $stmt->errorCode() . "\n";
} catch (PDOException $e) {
    echo "MySQL connection error: " . $e->getMessage();
}

// SQLite example
try {
    $sqlite = new PDO('sqlite:test.db');
    $sqlite->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    
    $stmt = $sqlite->prepare('SELECT * FROM non_existent_table');
    $stmt->execute();
    
    echo "SQLite error code: " . $stmt->errorCode() . "\n";
} catch (PDOException $e) {
    echo "SQLite connection error: " . $e->getMessage();
}

不同的数据库系统可能对相似的错误返回不同的 SQLSTATE 代码。此示例展示了如何在系统之间一致地处理错误。

errorCode 与 errorInfo

此示例比较了 errorCode 与更详细的 errorInfo 方法。

pdo_errorcode_vs_errorinfo.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 non_existent_table (name) VALUES (?)');
    $stmt->execute(['Test']);
    
    // Get just the SQLSTATE code
    $errorCode = $stmt->errorCode();
    echo "Error Code: $errorCode\n";
    
    // Get full error information
    $errorInfo = $stmt->errorInfo();
    echo "Full Error Info:\n";
    print_r($errorInfo);
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

errorCode 仅返回 SQLSTATE 代码,而 errorInfo 返回一个包含代码、驱动程序特定错误代码和错误消息的数组。使用 errorCode 进行简单检查,使用 errorInfo 进行详细诊断。

使用 errorCode 进行实际错误处理

此示例展示了处理不同错误代码的实际方法。

pdo_errorcode_handling.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 (email) VALUES (?)');
    $stmt->execute(['invalid_email']); // Assuming email has validation
    
    $errorCode = $stmt->errorCode();
    
    switch ($errorCode) {
        case '00000':
            echo "Success! Record inserted.\n";
            break;
        case '23000': // Integrity constraint violation
            echo "Error: Duplicate or invalid data.\n";
            break;
        case '42000': // Syntax error or access violation
            echo "Error: SQL syntax problem.\n";
            break;
        case 'HY000': // General error
            echo "Error: General database error.\n";
            break;
        default:
            echo "Unknown error occurred: $errorCode\n";
    }
} catch (PDOException $e) {
    echo "Connection error: " . $e->getMessage();
}

此示例演示了使用 switch 语句处理不同错误代码的实用方法。每个 SQLSTATE 代码都可以触发适合应用程序的特定错误处理逻辑。

最佳实践

来源

PHP PDOStatement::errorCode 文档

本教程介绍了 PDOStatement::errorCode 方法,并通过实际示例展示了其在不同数据库错误场景下的用法。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 PHP PDO 函数