嘿,我有一个带有PDO的数据库类和一些面向对象论坛的其他类:
class Database {
private $databaseConnection;
function __construct($path = "", $dbUsername = "", $dbPassword = ""){
$parts = explode('.',$path);
$documentType = array_pop($parts);
if(($path == "") || ((strcmp($documentType, "sq3") !== 0) && (strcmp($documentType, "sqlite") !== 0))) {
throw new Exception("The Database must bee .sq3 or .sqlite and Path must be stated");
}
$this->databaseConnection = new PDO('sqlite:' . $path, $dbUsername, $dbPassword);
$this->databaseConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->databaseConnection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
self::query('CREATE TABLE...)');
}
function query($sql, $params = NULL){
...
}
function getObjects($objectTable, $searchedForAttribute, $attributeValue){
...
}
function insertObject($object){
...
}
function updateObject($object){
...
}
function removeObject($object){
...
}
...//some other methods
function __destruct(){
unset($this->databaseConnection);
}
}
我应该使用例外吗?如:
function insertObject($object){
try {
...
}catch(PDOException $e){
throw new Exception($e->getMessage());
}
}
因此,我必须在其他地方捕获此异常并以不同的方式将其分发出去。例如:我有一个类用户和一个表用户。因此,如果填写了新的注册,我必须验证新用户的信息。因此,如果一个expactant User选择一个已经在数据库中的名称,我会抛出一个Exception,尽管我只需要一条消息给User,说明该名称已被分配。
所以我觉得如果我这样做会更好:
function insertObject($object){
try {
...
}catch(PDOException $e){
return "Username already assigned";
}
}
当然,我并不总是知道为什么会抛出异常,但在这种情况下,我会使用if-block验证数据。
那么在这种情况下我应该如何使用异常处理?
答案 0 :(得分:2)
你的问题很简单,但同时又很庞大(恕我直言)。
首先,如果您想通过ORM /模型"进行简单的数据库抽象,我建议您使用Doctrine或其他现成的ORM软件包。或者是一个框架。
如果(像我一样)你是一个像这样从头开始做事的真正的傻瓜,那么我会从痛苦的先前经历中得到一些建议。
如果你选择沿着异常路线走下去(I'专业人员 - 最初来自C / C ++背景)使用字符串值作为字符串位(给出例外的人性化消息来显示)和也给它一个机器友好的属性(对于将捕获它的代码)。
\PDOException
自然而然地指出数据库失败刚刚发生,例如"我失去了连接"或者" MySQL borked"。您可能希望让这些异常自行回到调用您的代码......
对于特定于模型的错误,我要创建适当的异常类。字面上:
class UserModelException extends \Exception {
... // Optional stuff here
}
然后,您可以在调用代码中捕获不同的排序错误:
try {
...
} catch (\UserModelException $e) {
...
} catch (\PDOException $e) {
...
}
等
当然,您可能希望捕获模型中的PDO异常,以确定某个类似于唯一键约束的内容是否爆炸 - 即指示用户名已存在。在这种情况下,您可能(在您的模型中)想要:
try {
...
} catch (\PDOException $e) {
if (...) { // unique constraint error - username already taken
throw new \UserModelException(...);
} else {
throw $e;
}
}
这是否有意义,是否有任何帮助?
我无法思考(在我的头脑中)我建议抛出文字\Exception
对象的情况 - 我总是在每个上下文中继承它基础。
答案 1 :(得分:1)
我应该使用例外吗
肯定是的。这是唯一的方法。
如:
}catch(PDOException $e){
throw new Exception($e->getMessage());
}
进行这样的重新投掷绝对没有意义。为什么不单独留下PDOException?
我应该在自己的数据库类中使用PDO抛出异常吗?
是的,你应该。
那么在这种情况下我应该如何使用异常处理?
你必须先了解两件事。
对于运行时异常(如查询失败),所需的处理不多。编写一个常见的异常处理程序,它正在执行一些记录消息和显示借口页面的常见工作。当然不应该向用户显示真正的错误消息。只是一个普遍的借口。
但是对于用户验证,请使用try..catch通过捕获您自己的UserValidationException 来查看是否所有数据都已经过验证。
换句话说,程序员的例外情况和用户的例外情况。你必须以不同的方式对待它们。 A"数据库必须是.sq3或.sqlite和Path必须说明"一个程序员,不应该向用户显示。相反,它必须被记录以供程序员参考,必须向用户显示借口页面并且必须停止程序。
A"用户名已经采取"是一个供用户使用,必须向他们展示。
要区分这两种类型的例外,必须使用不同的异常类。
这两种类型可能遇到的唯一情况是来自数据库的某些错误,可用于验证目的。在这种情况下,必须实现条件块,如另一个答案中所示。
但是,异常可能不便于验证用户输入,因为您可能希望收集所有可能的错误,而不是一个。在这种情况下,不要使用异常进行数据验证,而是逐个运行验证并将错误添加到数组中。