postgres php异常处理

时间:2015-12-02 17:26:14

标签: php postgresql exception pdo

我之前在SO上看到过这个问题,但答案似乎都没有完整。所以请...

我有使用PDO和PDOStatement的代码。它原本是在没有例外的情况下编写的,我将其转换为可以使用。

我的简单问题是:

  1. 在任何情况下,继续检查FALSE函数的返回值是否有用或必要(当这意味着"失败"),或者我可以简单地执行该方法并假设所有各种失败会引发异常吗?我在一个答案中看到了一个例子,其中有人被建议使用BOTH try-catch AND来测试FALSE的返回值 - 这实际上是必要的,它会产生一些非常难看的代码。
  2. 是否有一个正确的列表,哪些方法可以,哪些方法永远不会抛出异常?我已经看到了答案,如果你发现我们没有记录我们抛出的异常,那就提出错误"但这并不完全有用。我已经看到语句"手册页说明何时可以抛出异常",但是PDO :: query和PDOStatement :: execute页面没有提到例外 - 这肯定不是真的... 它可以?基本上我想知道准备,绑定[事物],获取[全部],执行还是其他一些人可能会或者永远不会抛出东西。
  3. 我不觉得我在问地球,如果必须的话,我可以查看代码,但是关于这个的手册文档肯定是坚如磐石的。

    [编辑添加示例]

    我现在发现自己有这样的代码块 - 我想通过删除返回值的测试来简化它,但我不能说服自己这是正确的。其他块使用execute()等等。

    try {
      /* I do not know whether beginTransaction throws an exception when it would otherwise return FALSE.
       * If it does then checking the return value is spurious, and the code cam be simplified.
       */
      if (FALSE == $customerDb->beginTransaction()) {
        Log::add("Database begin transaction failed.",
                  Log::ERROR);
      throw new Exception("Failed to begin a transaction.");
      }
    } catch (PDOException $e) {
      /* The documentation does not mention the possibility of
       *  beginTransaction() throwing any exception,
       *  even when we have configured all the other functions to do so.
       */
      Log::add("Database begin transaction threw an exception: " . $e->getMessage(),
               Log::ERROR);
      throw new Exception("Begin transaction threw an exception.");
    }
    

1 个答案:

答案 0 :(得分:0)

有三种错误处理策略,ERRMODE_SILENT(默认值),ERRMODE_WARNINGERRMODE_EXCEPTION。如果发生错误,只有最后一个使PDO抛出异常,所以除非你明确告诉PDO在异常模式下运行:

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

它不会抛出任何异常,除了PDO:__construct(),如果连接失败将抛出异常,无论PDO::ATTR_ERRMODE的值是什么。

来自doc:

  如果连接,

PDO::__construct()将始终抛出PDOException   无论当前设置了哪个PDO::ATTR_ERRMODE,都会失败。未捕获   例外是致命的。

我建议你阅读the documentation - 非常清楚PDO如何处理错误。

更新

在您的代码示例中,永远不会捕获异常,因为您将catch块异常键入PDO_Exception并且您正在抛出Exception - 这是较低的异常类型级别。如果要捕获所有异常类型,请将catch参数强制转换为Exception - 目前只捕获PDOException

话虽如此,让我们关注你对异常的困惑。在ERRMODE_SILENTERRMODE_WARNING中,除了来自PDO控制器的文件外,还有没有神秘的异常被抛出。否则,人们可能在他们并不真正了解/控制的PDO环境中工作 - 比如使用PDO的框架,但是在查询时抛出自己的异常,或者在特定情况下更改ATTR_ERRMODE。我建议你少关注文档下的讨论(因为有时可能会有一些有趣的东西,大多数时候它是来自困惑的人的评论)并且更多地关注文档本身。

让我们清楚PDO中出现错误的原因。

  1. 发生错误。如果它发生在PDO控制器中,则会抛出异常,并忽略所有后续步骤。

  2. 错误将根据the SQL-92 standard标准化(有关所有存在的返回代码,请参阅此链接)。来自doc:

      

    PDO标准化使用SQL-92 SQLSTATE错误代码字符串;各个PDO驱动程序负责将其本机代码映射到适当的SQLSTATE代码。

  3. PDO检查ATTR_ERMODE属性以了解它应如何处理此错误。

    1. ERRMODE_SILENT(默认模式)

      不会报告错误,因此您需要检查false的PDO函数的返回情况并检查PDO::errorCode()PDO::errorInfo()或{{3 },PDOStatement::errorCode()取决于您用来获取错误详情的对象。

    2. ERRMODE_WARNING

      ERRMODE_SILENT相同,但会抛出E_WARNING PHP错误。可能对开发有用,但您仍需要检查false的函数返回。

    3. ERRMODE_EXCEPTION

      将抛出PDO_Exception。将会有不需要来检查false的函数返回,因为当抛出异常时,将跳过下一行,PHP将转到catch块,或者如果没有任何catch块都会引发PHP错误。因此,在ERRMODE_EXCEPTION中运行时,您建议的实施是多余的。

  4. 所以是的,文档并没有说x函数会抛出异常,因为它会完全冗余。错误处理页面解释了您需要知道的所有内容。

    如果您仍然不相信,我建议您自己尝试:使用ATTR_ERRMODE和一些不同的PDO功能,并亲自看看。