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

Stu*_*ork 18 php sql pdo exception-handling

我正在使用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();
}
Run Code Online (Sandbox Code Playgroud)

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

nic*_*noe 15

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

<?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();
}
?>
Run Code Online (Sandbox Code Playgroud)

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

  • 通过不执行isset,如果$ _POST中的键不存在,您将收到通知.所以isset非常重要.第3个值是告诉您要绑定的值的类型,但这不是安全性.Immagine $ _POST ["foo"] = false; `myTable``foo`是一个BOOL; 并使用PDO :: PARAM_STR.PDO会向您插入"false"(字符串),并且可能会被解释为TRUE(bool).确保您的值处于良好类型,并且如果可能的话,在绑定它们之前将它们集中地转换为良好类型.添加第3个参数对于lisibility和琐碎的施法更好:) (2认同)

You*_*nse 11

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'];
Run Code Online (Sandbox Code Playgroud)

没有任何尝试或接听电话.因为这里没有处理异常的特定场景(简单的回声几乎不算作处理场景).

相反,让它冒泡到应用程序范围的错误处理程序(不要被术语吓到,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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Run Code Online (Sandbox Code Playgroud)

在连接之后.

  • 我相信 `23000` 是 `getCode()` 在这个特定示例中将返回的内容,填充在 `$e-&gt;errorInfo[0]` 中,希望适用于所有驱动程序(经过测试的 MySQL 和 MS SQL Server)。对于 MySQL,“1062”代码将填充在“$e-&gt;errorInfo[1]”中,而 MS SQL Server 将在“$e-&gt;errorInfo[1]”中填充“2627” (4认同)