PDO异常问题 - 如何捕获它们

时间:2012-06-19 14:01:41

标签: php sql exception-handling pdo

我正在使用PDO重新编写数据库的网站界面。我曾经使用mysql扩展,但我从来没有打扰过错误处理,而我所拥有的几个错误处理程序基本上是复制粘贴。

现在我想这样做。但是,我遇到了如何捕获错误的问题(MySQL中的“重复条目”,“空值”等错误)。我的声明中有多少需要在try块中?它应该都在那里吗?我正在使用Include()连接到我的数据库(它有自己的错误处理),因此它只是在此代码中有错误的查询执行。我无法弄清楚为什么在执行以下代码时没有发现错误:

try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "The user could not be added.<br>".$e->getMessage();
}

所以我的问题:所有这些都必须在try块中吗?我可以把执行块放在try块中吗?它应该捕获错误Duplicate value "John" in key "name",而是通过成功消息。 (当试图添加两个“John”用户时)。我检查了PHPMyAdmin;索引是唯一的,并且会按预期抛出错误,只是不使用此代码。

3 个答案:

答案 0 :(得分:14)

您应该查看文档。但是,如果你没有找到任何东西,你可以添加另一个捕获:

<?php
try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "DataBase Error: The user could not be added.<br>".$e->getMessage();
} catch (Exception $e) {
  echo "General Error: The user could not be added.<br>".$e->getMessage();
}
?>

这必须起作用,因为PHP的所有异常都插入了Exception本机PHP类中的herits。 (自5.0以来,如果我的记忆力很好)。

答案 1 :(得分:10)

  

PDO异常问题 - 如何捕捉它们

作为一项规则 -

DO NOT catch them

例如,您的代码应该以这种方式编写

$stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)");
$stmt->bindValue(":name", $_POST['name']);
$stmt->bindValue(":password", $_POST['password']);
$stmt->bindValue(":question", $_POST['question']);
$stmt->bindValue(":answer", $_POST['answer']);
$stmt->execute();
echo "Successfully added the new user " . $_POST['name'];

没有任何try或catch调用。 因为您没有处理异常的特定方案(简单的回声很少被视为处理方案)。

相反,让它冒泡到应用程序范围的错误处理程序(不要被术语吓到,PHP已经内置了一个)。

  

但是,我在捕捉错误方面遇到了问题(错误如&#34;重复输入&#34;,&#34;空值&#34;等等)。

只有在您拥有特定场景的情况下,您必须使用try-catch运算符,但您必须始终检查您所获得的错误是否是您所期望的错误。否则必须重新抛出异常:

try {
    $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}

当然(因为它原来是这个问题的问题),你必须在异常模式下设置PDO,只需在构造函数参数中添加代码

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
连接后

答案 2 :(得分:-2)

<?php
    $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)");

    $stmt->bindValue(":name", $_POST['name']);
    $stmt->bindValue(":password", $_POST['password']);
    $stmt->bindValue(":question", $_POST['question']);
    $stmt->bindValue(":answer", $_POST['answer']);
    $inserted = $stmt->execute();

    if($inserted)
        echo "Successfully added the new user " . $_POST['name'];
    else
        echo "Somethig get wrong";
?>