Postgres PHP 异常处理


postgres php exception handling

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

我有使用 PDO 和 PDOStatement 的代码。它最初是为无一例外地工作而编写的,我正在将其转换为工作。

我的简单问题是:

  1. 是否有任何情况可以继续检查函数的返回值是否为 FALSE(当这意味着"失败"(是有用或必要的,或者我可以简单地执行该方法并假设各种故障都会触发异常?我在答案中看到一个例子,建议有人同时使用 try-catch 和 FALSE 来测试 FALSE 的返回值 - 这实际上是必要的,会产生一些非常丑陋的代码。
  2. 是否有一个适当的列表,说明哪些方法可以,哪些方法永远不会引发异常?我见过答案说"如果你发现我们没有记录我们抛出的异常,请提出一个错误",但这并不完全有帮助。我见过"手册页说什么时候可以抛出异常"的陈述,但是 PDO::query 和 PDOStatement::execute 页面没有提到异常 - 这肯定不可能是真的......可以吗?从本质上讲,我想知道准备,绑定[事物],获取[全部],执行和其他一些可能会或永远不会扔东西。

我不觉得我在问地球,如果有必要,我可以看看代码,但可以肯定的是,这方面的手动文档应该是坚如磐石的。

[编辑以添加示例]

我现在发现自己有这样的代码块 - 我想通过删除返回值的测试来简化它,但我无法说服自己它是正确的。其他块使用 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.");
}

有三种错误处理策略,ERRMODE_SILENT(默认策略(、ERRMODE_WARNINGERRMODE_EXCEPTION 。只有最后一个使PDO在发生错误时抛出异常,因此除非您明确告诉PDO在异常模式下运行:

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

它不会抛出任何异常,除了PDO:__construct()如果连接失败,无论 PDO::ATTR_ERRMODE 的值是多少,它都会引发异常。

从文档中:

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

我建议您阅读文档 - PDO如何处理错误非常清楚。

更新

在代码示例中,当你将 catch 块异常键入到PDO_Exception并且要引发Exception(这是较低的异常类型级别(时,永远不会捕获异常。如果要捕获所有异常类型,请将 catch 参数转换为 Exception - 目前您的 catch 块捕获仅PDOException

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

让我们清楚PDO中的错误会发生什么。

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

  2. 错误将根据 SQL-92 标准进行标准化(有关存在的所有返回代码,请参阅此链接(。从文档:

    PDO

    在使用SQL-92 SQLSTATE错误代码字符串方面进行了标准化;各个PDO驱动程序负责将其本机代码映射到相应的SQLSTATE代码。

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

    1. ERRMODE_SILENT(默认模式(

      该错误不会被报告,因此您需要检查 PDO 函数是否返回false并检查PDO::errorCode()PDO::errorInfo()PDOStatement::errorCode()PDOStatement::errorInfo()具体取决于您用于获取错误详细信息的对象。

    2. ERRMODE_WARNING

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

    3. ERRMODE_EXCEPTION

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

所以是的,文档没有说 x 函数会引发异常,因为它是完全多余的。错误处理页面解释了您需要了解的所有内容。

如果你还是不服气,我建议你自己试试:玩ATTR_ERRMODE和一些各种PDO功能,自己看看。