【发布时间】:2012-07-22 01:19:42
【问题描述】:
我正在编写自己的 API 实现。这个 API 的资源之一是/user,我可以将POST 一个JSON 字符串传递给这个,解析它并将它发送到一个UserService,它有一个addUser 方法。现在显然我不能允许两个用户拥有相同的用户名。到目前为止,这是我必须要做的。
protected function handlePost() {
$user = json_decode($this->getRequest()->getRequestData(), true);
try {
$createdUserId = $this->userService->addUser(
$user['username'],
$user['password'],
$user['typeId'],
$user['companyId']
);
} catch (PDOException $e) {
$this->getResponse()->setStatus(102);
}
if ($createdUserId)
$this->getResponse()->setStatus(101);
$this->getResponse()->sendResponse();
}
这个函数在 HTTP 请求被解析后被调用。如您所见,我在关联数组中获得了 $user 对象。然后我将这些值用作$this->userService->addUser 方法的参数。
这是addUser() 方法:
public function addUser($username, $password, $type, $companyId) {
$sth = $this->dbh->prepare('INSERT INTO app_user
(username, password, typeId, companyId)
VALUES (?, ?, ?, ?)');
$userAdded = $sth->execute(array($username, md5($password), $type, $companyId));
return ($userAdded)
? $this->dbh->lastInsertId()
: null;
}
现在,如果 $sth->execute 由于某种原因失败,我会返回 null(并且不会返回状态码 101 或 102,我知道这一点)。但是如果用户名已经存在,PDO 会抛出异常,我在上面的 handlePost() 方法中捕获了该异常。
我的问题当然是已经被占用的用户名并不例外,不应该这样处理,但我真的不知道应该如何处理?
我必须能够区分触发的唯一约束和触发的其他一些(可能是并发问题),以便我可以将适当的状态代码发送回 API 的使用者。
一个明显的解决方案是检查用户名是否存在于单独的查询中,但出于显而易见的原因,我更愿意限制对数据库的调用。
我怎样才能优雅地解决这个问题?如果我必须使用异常,是否有特定 PDO 异常的列表,这样我就不必使用通用的PDOException?
【问题讨论】:
-
告诉我是否正确 - 您想在不使用 SQL 的情况下检查用户是否存在于数据库中?
-
您的代码表明您正在编写 API,但您的文本表明您正在实现 API。我很困惑!
-
@Yehonatan 不不,我知道这是不可能的:p,我只想知道是否有办法检查它,而不必使用异常来处理它并将查询数量限制为DB最好是1。
-
@Adnan,我正在自己编写消费者和提供者部分。
-
两个选项,做另一个查询,或者将用户名设置为唯一键并检测插入失败。