我之前在SO上看到过这个问题,但似乎没有一个答案是完整的。所以请...
我有使用 PDO 和 PDOStatement 的代码。它最初是为无一例外地工作而编写的,我正在将其转换为工作。
我的简单问题是:
- 是否有任何情况可以继续检查函数的返回值是否为 FALSE(当这意味着"失败"(是有用或必要的,或者我可以简单地执行该方法并假设各种故障都会触发异常?我在答案中看到一个例子,建议有人同时使用 try-catch 和 FALSE 来测试 FALSE 的返回值 - 这实际上是必要的,会产生一些非常丑陋的代码。
- 是否有一个适当的列表,说明哪些方法可以,哪些方法永远不会引发异常?我见过答案说"如果你发现我们没有记录我们抛出的异常,请提出一个错误",但这并不完全有帮助。我见过"手册页说什么时候可以抛出异常"的陈述,但是 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_WARNING
和 ERRMODE_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_SILENT
或ERRMODE_WARNING
中没有抛出神秘的异常,除了来自PDO控制器的异常 - 这是有记录的。否则,人们可能在他们并不真正了解/控制的PDO环境中工作 - 例如使用PDO但为查询抛出自己的异常的框架,或在特定情况下更改ATTR_ERRMODE
。我建议你少关注文档下的讨论(因为有时其中可能有有趣的东西,大多数时候是来自困惑的人的评论(,而更多地关注文档本身。
让我们清楚PDO中的错误会发生什么。
发生错误。如果它发生在PDO控制器中,将引发异常,并且将忽略所有后续步骤。
错误将根据 SQL-92 标准进行标准化(有关存在的所有返回代码,请参阅此链接(。从文档:
PDO
在使用SQL-92 SQLSTATE错误代码字符串方面进行了标准化;各个PDO驱动程序负责将其本机代码映射到相应的SQLSTATE代码。
PDO检查
ATTR_ERMODE
属性以了解它应如何处理此错误。ERRMODE_SILENT
(默认模式(该错误不会被报告,因此您需要检查 PDO 函数是否返回
false
并检查PDO::errorCode()
、PDO::errorInfo()
或PDOStatement::errorCode()
,PDOStatement::errorInfo()
具体取决于您用于获取错误详细信息的对象。ERRMODE_WARNING
与
ERRMODE_SILENT
相同,但会抛出E_WARNING
PHP 错误。对于开发可能很有用,但您仍然需要检查函数返回false
。ERRMODE_EXCEPTION
将抛出
PDO_Exception
。无需检查函数返回false
因为当抛出异常时,将跳过下一行,PHP 将转到 catch 块,或者如果没有任何 catch 块,它将抛出 PHP 错误。因此,您建议的实现在ERRMODE_EXCEPTION
中运行时是多余的。
所以是的,文档没有说 x 函数会引发异常,因为它是完全多余的。错误处理页面解释了您需要了解的所有内容。
如果你还是不服气,我建议你自己试试:玩ATTR_ERRMODE
和一些各种PDO功能,自己看看。