1

次の認証クラスの例で例外をスローする場合は、処理する状況ごとに異なる例外をスローすることをお勧めします。例:

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;
}

私は例外に不慣れであり、両方の解決策が等しく実行可能であるように思われるので、私は尋ねます。おそらく他の解決策が完全にありますか?

興味深い補足:いくつかの回答を受け取るまで、「あなたの好みは何ですか」という質問をしていることに気づきませんでした。私は単一の推奨される方法を期待していました。

4

3 に答える 3

1

片方が正しいとか片方が間違っているとは言いません。「この方法をお勧めしますか、この方法をお勧めしますか」と質問すると、大規模なグループで右の神経に当たった場合、大きなポットを簡単にかき立てることができます。

特にあなたの質問に関しては、両方とも異なるタイプの例外をスローするための有効で許容可能な方法です-そして私は両方をかなり頻繁に見ました。

ただし、ほぼすべての言語の大規模なアプリケーションでは、一番下の方法がよく見られます。これは、私自身の個人的なスタイル/好みでもあります。AuthException例外の単一の「タイプ」をスローし、例外コードを指定することは非常に明確で簡潔だと思います。

(プログラミングの観点から)より説明的なものにしたい場合はenum、コードに疑似*セットアップを使用して、ユーザーフレンドリーな説明を与えることができます。

class AuthExceptionCode {
    const USER_EXISTS = 0;
    const EMAIL_EXISTS= 1;
    // ....
}

コードで例外をスローするには:

throw new AuthException('error message', AuthExceptionCode::USER_EXISTS);

Exception実際のカスタムクラスがある場合、つまり--youの場合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
                // ...


* EnumerationsPHPにネイティブではないため、const(サードパーティのクラス/プラグインを使用せずに)を使用するのが最も簡単な方法です。

于 2012-08-17T19:18:11.157 に答える
1

一般に、ベスト プラクティスは、例外に単一の例外条件を含めることだと思います。たとえば、SPL の例外を考えてみましょう。あなたは投げInvalidUserArgumentExceptionますInvalidEmailArgumentExceptionか?いいえ。SPLInvalidArgumentExceptionをスローし、詳細に基づいて例外メッセージを変更するだけです (たとえば、「無効なユーザー」または「無効な電子メール」)。AuthExceptionそうは言っても、コードとスイッチを使用する代わりに、例外メッセージを直接出力するだけで、単一のものを使用してメッセージを変更する必要があります(2番目の例で行ったように)。

try {
    $auth->adduser(...);
} catch (AuthException $e) {
    $output = $e->getMessage();
}

echo $output;
于 2012-08-17T19:06:05.857 に答える
0

発生する可能性のある例外ごとに個別の catch ステートメントを使用する一番上の方法を好みますが、状況によって異なります。意味を理解するのが難しい非常に長い例外クラス名がある場合は、それらを少しグループ化します.

于 2012-08-17T18:54:23.250 に答える