40

次のようなメソッドを持つクラスがあるとします。

/*
 *
 * Loads the user from username.
 *
 * @param string $username The username
 *
 * @return UserInterface
 *
 * @throws userNotFoundException if the user is not found
 */
public function getUser($username)
{
    // someFunction return an UserInterface class if found, or null if not.
    $user = someFunction('SELECT ....', $username);
    if ($user === null) {
        throw new userNotFoundException();
    }

    return $user
}

ここで、XYZ の理由で/ /をsomeFunctionスローできるとしましょう。私は何をすべきか?そして、そうではありませんか?InvalidArgumentExceptionRuntimeExceptionPDOException

ナンバー1

someFunctionphp-docs でスローされる可能性のあるすべての例外を追加します。

/*
 *
 * Loads the user from username.
 *
 * @param string $username The username
 *
 * @return UserInterface
 *
 * @throws userNotFoundException if the user is not found
 * @throws InvalidArgumentException
 * @throws ...
 */

2番

メソッドが例外をスローするように try-catch ブロックを追加します。

/*
 *
 * Loads the user from username.
 *
 * @param string $username The username
 *
 * @return UserInterface
 *
 * @throws userNotFoundException if the user is not found
 * @throws RuntimeException 
 */
public function getUser($username)
{
    try {
        $user = someFunction('SELECT ....', $username);
    } catch (Exception $e) {
        throw new RuntimeException();
    }

    if ($user === null) {
        throw new userNotFoundException();
    }

    return $user
}

ナンバー 3

何もしないでください。

4

4 に答える 4

24

@throws個人的には、Java のチェック済み例外と同様に扱うことを検討します

これが Java で機能する方法は、基本的に、RuntimeException から継承する例外をスローでき、処理する必要がないということです。他のタイプの例外には、それらを処理するための try-catch ブロックが必要です。この処理コードは呼び出し元にある必要があります。

基本的にPHPでは次のようになります:

メソッドに@throws注釈がある場合、その例外を処理するコード追加する必要があります。

言及されていない例外は、呼び出し元のコードで処理するためのオプションです。


さて、私自身、この原則を 100% 守っているわけではありません。例外処理全体はプログラマーの好み次第ですが、これは合理的な方法で処理できると私が考える方法についてのいくつかの考えです。

于 2013-03-23T13:55:55.707 に答える
12

ドキュメントに関しては、関数が明示的に例外をスローする場合は、関数のドキュメントに含める必要があります。したがって、各ステートメントについて、対応する が PHP ドキュメントにthrowあるはずです。@throws

処理に関しては、例外がスローされたときに実行する必要がある操作がある場合は、それをキャッチします。それ以外の場合は、バブルアップさせます-catch後でそれを処理するステートメントがある場合.

アップデート:

数年後、例外がまだモジュールの抽象化レベルに関連している場合にのみ、例外を変更せずに「バブルアップ」させるべきだという意見に変わりました。キャッチして再スローする戦略を採用して、例外をより意味のあるものにする必要があります。また、抽象化の基礎となるモジュールに関する情報の不必要な開示を回避することで、エラー処理をより安全にする必要があります。

/**
 * @throws UserNotFoundException
 */
public function getUser($username)
{
    try {
        $user = someFunction('SELECT ....', $username);
    } catch (DatabaseException $dbe) {

        /* Re-throw since a database exception may no longer be
         * meaningful to the caller.
         */
        throw new UserNotFoundException();
    }

    return $user
}
于 2013-03-23T14:58:50.797 に答える
8

ドキュメントのメンテナンスの観点から、特にスローされる例外に対してのみ @throw 行を追加します。そうしないと、ドキュメントがすぐに古くなってしまいます。

于 2013-03-23T13:56:04.587 に答える