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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11102644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:45:34  来源:igfitidea点击:

PDO Exception Questions - How to Catch Them

phpsqlexception-handlingpdo

提问by StuckAtWork

I'm using PDO to re-write a website interface for a database. I used to use the mysql extension, but I had never bothered with error handling, and the few error handlers I had were basically copy-paste.

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

Now I'd like to do this right. However, I'm having issues catching the errors how I'd like (errors like "Duplicate Entry", "Null Value" etc in MySQL). How much of my statement needs to be in the try block? Should all of it be in there? I'm using an Include()to connect to my DB (which has its own error handling), so it's only the query execution which has errors in this code. I can't figure out why it's not catching an error when executing the following code:

现在我想正确地做这件事。但是,我在捕捉我想要的错误时遇到了问题(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();
}

So my questions: does ALL OF THAT have to be in the try block? Can I just put the execute in the try block? It should catch the error Duplicate value "John" in key "name", but instead goes through with the success message. (When trying to add two "John" users). I checked in PHPMyAdmin; the index is unique and does throw the error as expected, just not using this code.

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

采纳答案by niconoe

You should look at the documentation. But If you dont find anything, you can add another catch :

你应该看看文档。但是如果你没有找到任何东西,你可以添加另一个 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();
}
?>

This must work because all exceptions of PHP plugins herits from the Exception native PHP class. (Since 5.0 if my memory is well).

这必须有效,因为 PHP 插件的所有异常都继承自 Exception 原生 PHP 类。(如果我记性好的话,从 5.0 开始)。

回答by Your Common Sense

PDO Exception Questions - How to Catch Them

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

As a rule -

通常——

DO NOT catch them.

不要抓住它们

For example, your code here should be written this way

例如,你这里的代码应该这样写

$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'];

without any try or catch calls. Because you have no particular scenario for handling an exception here(a simple echo is scarcely counts as a handling scenario).

没有任何 try 或 catch 调用。因为您在这里没有处理异常的特定场景(简单的回声几乎算作处理场景)。

Instead, let it bubble up to the application-wide error handler (don't be scared by the term, PHP already has a built-in one).

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

However, I'm having issues catching the errors how I'd like (errors like "Duplicate Entry", "Null Value" etc in MySQL).

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

Only in case if you have a certain scenario, you have to use try-catch operator, but you have to always check, whether the error you've got is one you expected. Otherwise an exception have to be re-thrown:

仅当您遇到某种情况时,才必须使用 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;
    }
}

and of course (as it turned out to be the vere problem for this question), you have to set up PDO in exception mode, either in a constructor parameter of simply by adding the code

当然(事实证明这是这个问题的真正问题),您必须在异常模式下设置 PDO,或者在构造函数参数中简单地添加代码

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

right after connect.

连接后。

回答by Sami FAREH

<?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";
?>