我正在编写自己的 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
?