我应该如何在php auth类中抛出异常?

时间:2012-08-17 18:49:30

标签: php exception

在以下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;
}

我问,因为我不熟悉异常,两种解决方案似乎同样可行。也许完全有其他解决方案?

有趣的旁注:在收到几个答案之前,我没有意识到我问的是“你的偏好是什么”的问题。我期待一种推荐的方法。

3 个答案:

答案 0 :(得分:1)

一般来说,我认为最佳做法是异常应包含单一的例外情况。例如,以SPL例外为例。你会抛出InvalidUserArgumentExceptionInvalidEmailArgumentException吗?不。您将抛出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语句的顶级方法,但它取决于..如果你发现自己有很长的异常类名,很难理解它们的含义,那么我会将它们分组一点点。