我之前在SO上看到过这个问题,但答案似乎都没有完整。所以请...
我有使用PDO和PDOStatement的代码。它原本是在没有例外的情况下编写的,我将其转换为可以使用。
我的简单问题是:
我不觉得我在问地球,如果必须的话,我可以查看代码,但是关于这个的手册文档肯定是坚如磐石的。
[编辑添加示例]
我现在发现自己有这样的代码块 - 我想通过删除返回值的测试来简化它,但我不能说服自己这是正确的。其他块使用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.");
}
答案 0 :(得分:0)
有三种错误处理策略,ERRMODE_SILENT
(默认值),ERRMODE_WARNING
和ERRMODE_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_SILENT
或ERRMODE_WARNING
中,除了来自PDO控制器的文件外,还有没有神秘的异常被抛出。否则,人们可能在他们并不真正了解/控制的PDO环境中工作 - 比如使用PDO的框架,但是在查询时抛出自己的异常,或者在特定情况下更改ATTR_ERRMODE
。我建议你少关注文档下的讨论(因为有时可能会有一些有趣的东西,大多数时候它是来自困惑的人的评论)并且更多地关注文档本身。
让我们清楚PDO中出现错误的原因。
发生错误。如果它发生在PDO控制器中,则会抛出异常,并忽略所有后续步骤。
错误将根据the SQL-92 standard标准化(有关所有存在的返回代码,请参阅此链接)。来自doc:
PDO标准化使用SQL-92 SQLSTATE错误代码字符串;各个PDO驱动程序负责将其本机代码映射到适当的SQLSTATE代码。
PDO检查ATTR_ERMODE
属性以了解它应如何处理此错误。
ERRMODE_SILENT
(默认模式)
不会报告错误,因此您需要检查false
的PDO函数的返回情况并检查PDO::errorCode()
,PDO::errorInfo()
或{{3 },PDOStatement::errorCode()
取决于您用来获取错误详情的对象。
ERRMODE_WARNING
与ERRMODE_SILENT
相同,但会抛出E_WARNING
PHP错误。可能对开发有用,但您仍需要检查false
的函数返回。
ERRMODE_EXCEPTION
将抛出PDO_Exception
。将会有不需要来检查false
的函数返回,因为当抛出异常时,将跳过下一行,PHP将转到catch块,或者如果没有任何catch块都会引发PHP错误。因此,在ERRMODE_EXCEPTION
中运行时,您建议的实施是多余的。
所以是的,文档并没有说x函数会抛出异常,因为它会完全冗余。错误处理页面解释了您需要知道的所有内容。
如果您仍然不相信,我建议您自己尝试:使用ATTR_ERRMODE
和一些不同的PDO功能,并亲自看看。