【问题标题】:How to handle PDO connection errors properly?如何正确处理 PDO 连接错误?
【发布时间】:2019-09-03 16:13:23
【问题描述】:

出于安全原因,我尝试使用 PHP/MySQL 处理或捕获可能出现的错误,并想知道我是否做得对。 第一种情况:我将其用作函数,并在需要数据库连接时始终调用它。 第二种情况:不知道怎么处理。我将所有准备好的语句放在if 条件中,但这很尴尬。 那么$stmt->execute 呢?这也可能会失败,并且在 if 条件下也处理这个问题真的会让人感到困惑。 我希望有更好的方法。

第一:

function pdo () {
  try {
    $pdo = new PDO('mysql:host=localhost;dbname=dbname', 'user', 'pw');
  }
  catch(PDOException $e) {
    header("Location: handle_error.php");
    exit;
  }
  return ($pdo);
}

第二个:

if ($stmt = $pdo->prepare("SELECT a FROM b WHERE c = :c")) {
  $stmt->execute(array(':c' => $c));
  $result = $stmt->fetch();
  echo 'All fine.';
}
else {
  echo 'Now we have a problem.';
}

【问题讨论】:

  • 欢迎你 Stack Overflow!我已经有了一流的答案,但你问的方式表明这在 Stack Overflow 上是相当离题的,你的问题更适合 codereview.stackexchange.com。请在那里询问或将其改写为“如何...”,例如@如何正确连接 PDO 并处理错误”

标签: php pdo error-handling


【解决方案1】:

您当前的代码存在一些缺陷。让我给你几个指点。

  1. 您不需要已创建的函数,至少在当前形式中不需要。每次调用此函数时,它都会创建一个新的 PDO 对象,这会妨碍脚本的性能。理想情况下,您希望在整个脚本的整个执行过程中只有一个连接。

  2. 创建新的 PDO 连接时,您需要记住 3 件事:设置正确的连接字符集、启用错误报告和禁用模拟准备。

    • 正确的字符集很重要。如果没有它,您的数据可能会被损坏,甚至让您容易受到 SQL 注入的攻击。推荐的字符集是utf8mb4
    • 启用错误报告可以省去手动检查每个函数调用是否失败的麻烦。您只需要告诉 PHP 在发生错误时触发异常,并找到一种合适的方式在您的服务器上记录错误(阅读更多:My PDO Statement doesn't work
    • 默认情况下启用模拟准备,但事实是没有它们你会更好。如果您的数据库支持本机准备语句,并且大多数都支持,那么请改用它们。

    完整的代码应该是这样的:

    $options = [
        \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_EMULATE_PREPARES => false,
    ];
    $pdo = new \PDO('mysql:host=localhost;dbname=dbname;charset=utf8mb4', 'user', 'pw', $options);
    
  3. 不要捕获异常,除非您知道如何处理它们并且确定需要这样做。例外情况最好保留;让 PHP 与其他异常/错误/警告一起处理它们。毕竟为什么只为 PHP 异常做一个异常呢?所有 PHP 错误都应该被同样处理。无论您做什么,都不要在屏幕上手动打印(包括dieexitechovar_dump)错误消息。如果此类代码进入生产环境,这将是一个巨大的安全问题。

如果您的 PDO 连接设置为在错误时引发异常,则您永远不需要使用 if 语句来检查 prepare()execute() 的返回码。

【讨论】:

  • 感谢您详细解释pdo连接。现在我不再使用连接函数,而是在每个需要它的 php 文件的顶部包含一个单独的 database_setting.php 文件,其中包含正确的信息。我希望到目前为止这是正确的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 2012-07-07
  • 2021-08-29
  • 2021-10-23
  • 2020-02-21
相关资源
最近更新 更多