在以下auth类示例中抛出异常时,建议为每个要处理的情况抛出不同的异常,例如:
addUser(...) {
// normal database code here...
switch(TRUE) {
case ($username_exists):
throw new UserExists('Cannot create new account. Account username ' . $un . ' already exists.');
case ($email_exists):
throw new EmailExists('Cannot create new account. Account email ' . $email . ' already exists.');
}
}
//to be called externally by...
try {
$auth->adduser(...);
} catch (UserExists) {
$output = 'That username is already taken.';
} catch (EmailExists) {
$output = 'That email is already being used.';
} catch (AuthException $e) {
$output = $e->getMessage();
}
echo $output;
}
或者是否建议使用唯一的异常代码抛出一般的“类型”异常?例如...
addUser(...) {
// normal database code here...
switch(TRUE) {
case ($username_exists):
throw new AuthException('Cannot create new account. Account username ' . $un . ' already exists.', 10);
case ($email_exists):
throw new AuthException('Cannot create new account. Account email ' . $email . ' already exists.', 20);
}
}
//to be called externally by...
try {
$auth->adduser(...);
} catch (AuthException $e) {
switch($e->getCode()) {
case 10:
$output = 'That username is already taken.';
break;
case 20:
$output = 'That email is already being used.';
break;
default:
$output = $e->getMessage();
}
echo $output;
}
我问,因为我不熟悉异常,两种解决方案似乎同样可行。也许完全有其他解决方案?
有趣的旁注:在收到几个答案之前,我没有意识到我问的是“你的偏好是什么”的问题。我期待一种推荐的方法。
答案 0 :(得分:1)
一般来说,我认为最佳做法是异常应包含单一的例外情况。例如,以SPL例外为例。你会抛出InvalidUserArgumentException
和InvalidEmailArgumentException
吗?不。您将抛出SPL InvalidArgumentException
,并根据详细信息更改异常消息(例如“无效用户”或“无效的电子邮件”)。也就是说,恕我直言,您应该使用单个AuthException
并且只是改变消息(就像您在第二个示例中所做的那样),而不是使用代码和开关,只是直接输出异常消息:
try {
$auth->adduser(...);
} catch (AuthException $e) {
$output = $e->getMessage();
}
echo $output;
答案 1 :(得分:1)
我不会说一种方法是正确的,一种方法是错误的 - 并且如果这个问题在一个大群体中遇到正确的神经,那么问一个“就这种方式推荐这种方式”很容易引起一大锅。 / p>
关于你的具体问题,两者都是有效和可接受的方式来抛出不同类型的例外 - 我经常看到这两种情况。
然而,在几乎所有语言的大规模应用中,我经常看到底层方法 - 这也是我自己的个人风格/偏好。我认为抛出一个“类型”的异常AuthException
,并指定一个异常代码是非常简洁明了的。
如果您希望它更具描述性(从编程的角度来看),您可以使用伪 - enum
*设置代码来提供用户友好的描述:
class AuthExceptionCode {
const USER_EXISTS = 0;
const EMAIL_EXISTS= 1;
// ....
}
使用代码抛出异常:
throw new AuthException('error message', AuthExceptionCode::USER_EXISTS);
如果您有一个实际的自定义 - Exception
课程,即 - extend Exception
,您可以将代码方向放在课程本身中:
class AuthException extends Exception {
const MISC = -1;
const USER_EXISTS = 0;
const EMAIL_EXISTS= 1;
public function __construct($message, $code = self::MISC) {
switch ($code) {
case self::USER_EXISTS:
// example on how to access the codes from within the class
// ...
* Enumerations
不是PHP原生的,因此使用const
是最简单的方法(不使用第三方类/插件。
答案 2 :(得分:0)
我更喜欢你可以发生的每个异常都有一个单独的catch语句的顶级方法,但它取决于..如果你发现自己有很长的异常类名,很难理解它们的含义,那么我会将它们分组一点点。