web-dev-qa-db-ja.com

ベストプラクティス:php-docでの@throwsの使用、およびその処理方法

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

/*
 *
 * 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
}

someFunctionがXYZの理由でInvalidArgumentException/RuntimeException/PDOExceptionをスローするとします。私は何をすべきか? そして何をしないのですか?

1番

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

/*
 *
 * 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番

何もしないでください。

30
Federkun

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

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

基本的にPHPこのように:

メソッドに@throwsアノテーション、あなたする必要があります例外を処理するコードを追加します。

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


今、私はこの原則を100%自分で守っていません。例外処理の全体は、プログラマーの好み次第ですが、これは、それを合理的な方法で処理できると私がどのように考えることができるかについての単なる考えです。

12

ドキュメントに関しては、関数explicitlyが例外をスローする場合、関数のドキュメントに含める必要があります。したがって、各throwステートメントに対して、PHPドキュメントに対応する@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
}
9
Czar Pino

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

7
acutesoftware

番号2ですが、スローアクションはリターンの前に発生するため、おそらくリターンの前にスローします...

0
tfont