24

我正在使用 PDO 为数据库重写网站界面。我曾经使用 mysql 扩展,但我从来没有为错误处理而烦恼,我拥有的少数错误处理程序基本上是复制粘贴。

现在我想正确地做到这一点。但是,我在捕捉我想要的错误时遇到了问题(MySQL 中的“重复条目”、“空值”等错误)。有多少我的语句需要在 try 块中?所有的东西都应该在那里吗?我正在使用 anInclude()连接到我的数据库(它有自己的错误处理),所以只有查询执行在这段代码中有错误。我无法弄清楚为什么在执行以下代码时它没有捕获错误:

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;该索引是唯一的,并且会按预期抛出错误,只是不使用此代码。

4

5 回答 5

20

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

<?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 类。(如果我的记忆好的话,从 5.0 开始)。

于 2012-06-19T14:20:35.510 回答
15

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

通常——

不要抓住他们

比如你这里的代码应该这样写

$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 已经有一个内置的)。

但是,我在捕捉我想要的错误时遇到了问题(MySQL 中的“重复条目”、“空值”等错误)。

只有在遇到某种情况时,您才必须使用 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 );

连接后。

于 2016-05-05T15:12:03.997 回答
0

你可以做的是从重复条目之类的东西中捕获错误代码,然后if(str_contains($e, '1062 Duplicate entry')) {在你的内部使用类似的东西catch (PDOException $e) {

于 2021-10-15T11:51:20.627 回答
0

建立新的 PDO 连接时正确抛出错误

       try{  try{
            $this->pdo = new \PDO($this->dsn,$this->options);
            $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
            //Display PDO Errors
            $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);



        }catch (\PDOException $e) {

            throw new CustomException ($e->getMessage());
        }

    }catch (CustomException $e)
    {

        $e->render();
    }
于 2021-10-01T13:53:01.447 回答
-3
<?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";
?>
于 2019-09-08T23:35:09.247 回答