我正在编写一个需要数据库连接的库,因此它要求用户将PDO对象作为构造函数的参数传递。
但正如你们许多人所知,PDO有3种不同的错误报告机制:静默模式,警告模式和异常模式(http://www.php.net/manual/en/pdo.error-handling.php)。
问题是每种模式都需要不同类型的错误处理代码。接受我不能强迫用户使用我的首选模式,我认为我的选择是:
因此1可以破坏用户的代码,2看起来像不必要的重复,3非常尴尬,4不是那么尴尬但仍然很尴尬,仍然容易破坏用户的代码。
所以我要求那里的图书馆作家,你怎么处理这个?
答案 0 :(得分:1)
好的,不确定这是否是适合此类问题的网站,但首先,让我向您简要介绍一下您的选项,并告诉您哪些 IMO 更好选项。然后我会在将来的编辑中解释所有这些。
PDO
实例,但至少用户有一个明确的API,并且知道可能的错误的结果是什么(例如{{1} } + PDO
=>您的API将始终抛出异常
现在,为什么你的第一个选择不是一个可行的方法? (再次:这是我的意见)
假设我要使用你的代码,并且有类似的东西:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
现在,如果您将PDO设置为抛出异常,我就不会抓住任何异常。我的代码没有以处理//code
$this->db = new PDO($dsn, $usr, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
$this->dependency = new Your\Lib\Stuff($this->db);
//code
$this->db->query('bad query');
实例的方式写入,因此它会导致整个应用程序停止运行。更重要的是,当发生这种情况时,谁会说我不会在调试时添加此行:
PDOException
这不是一条安全的道路,所以不要这样做。
下一步:克隆$this->dependency = new Your\Lib\Stuff($this->db);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);//override your setting
只是行不通。如果你有一个愚蠢的人写自己的课程从PDO
扩展,这是可能的:
PDO
在这种情况下,class BadIdea extends PDO
{
public function __clone()
{//disable clone
return false;
}
}
仍将作为$db = new BadIdea()
的实例传递(测试PDO
,然后调用function foo(PDO $arg){echo 'argument is instance of PDO';}
,将工作) 。现在你无法克隆,你的lib就失败了。
lib或框架应该写得足够通用,以便重用它。如果您正在编写代码,在考虑特定用例时,您可能会发现每次要再次使用它时都要编辑代码。
除非您打算创建自己的lib(在这种情况下,用户无论如何都不必传递自制的DB连接),错误处理不应该是您的lib的任务。
您的代码应该在发生意外的事件时抛出异常。您不能期望编写处理所有这些情况的代码:
foo(new BadIdea)
或者更糟:
$yourInstance->pass('Invalid query');
$yourInstance->select('INSERT ...');//valid query, wrong method
$your instance->query(array('invalid', 'argument'));
当您处理lib内部的错误时,您的用户将如何处理这些情况?事务是用户做出的一个有意识的决定,在事务期间可能发生的任何异常,无论是查询中的错误还是第三方方法抛出的异常都可能导致事务不得不回滚。
您的lib范围不够广泛,无法了解用户代码中引发的异常。