1

数日前、このようなエラーに対処しました...

exit( 'Error!' );

or exit( 'Error!' );

えっ?=] 今、私は例外を学ぼうとしています。ここまでたどり着いた...

http://pastie.org/1555970

それはそれらの正しい使用ですか?それらについてもっと情報を得ることができれば素晴らしいことです。例外がスローされたファイルとそのファイルの行のように。組み込みメソッド (Exception クラス内) があることは知っていますが、何とか拡張したいので、記述する必要はありません...

throw new My_Exception( '...' );

catch( My_Exception $e ) {

  echo $e->my_method();

}

...しかし、古い構文を使用します。

throw new Exception( '...' );

catch( Exception $e ) {

  echo $e->getMessage();

}

...または、例外についてもっと考えたことはありますか? それらに対処する方法は?助けて!=]

4

3 に答える 3

2

例外は、見つけたエラーに基づいて入力する必要があります。Spl 例外は良い出発点ですが、実際には独自の例外も作成する必要があります。私が使用するいくつかの一般的なもの:

  • FileNotFoundException extends RuntimeException<-自明
  • HTTPException extends RuntimeException<- 200 以外の結果が検出された場合に http クラスに使用されます
  • DatabaseQueryException extends LogicException<- データベース クエリ エラーに使用

具体的に入力することで、コード内のエラーを処理できます。では、HTTP リソースを取得したいとしましょう。404 以外で失敗した場合は、バックアップ URL を試してください。あなたはそれを行うことができます:

try {
    return getHttp($url1):
} catch (HttpException $e) {
    if ($e->getCode() != 404) {
        try {
            return getHttp($url2);
        } catch (HttpException $e2) {
            //It's ok to ignore this, since why know it's an HTTP error and not something worse
            return false;
        }
    } else {
        return false;
    }
}

あなたが投稿したサンプルコードに関する限り、私はいくつかのことを変更します:

  1. よりセマンティックな意味を持つため、スローされた例外を に変更しますInvalidArgumentException(生の例外をスローすることはほとんどありません)。

  2. 絶対に避けようとする必要catch(Exception $e)があります。どの例外がスローされたのかわからないので、どうすればそれを処理できますか?

  3. 処理方法を知っていると合理的に確信している例外のみをキャッチします (エラーの出力/ログは処理されず、例外の有用性が失われます)。netiher が実際に例外 を処理しているため、 orのようなものは表示されません。catch($e) { logerror($e); }catch($e) { print $e->getMessage(); }

  4. catch ブロックで例外の原因を修正または回避しない場合は、例外を再スローする必要があります。スタック内のあなたの上にあるコードがそれを処理しようとします。これは、あらゆる場所で再利用されるライブラリとクラスに特に当てはまります。

    現在、ユーザー インターフェイスでは、例外をキャッチしてユーザーにエラー メッセージを表示することが許容される場合があります。したがって、例外のメッセージを出力する例は問題ないかもしれませんが、そのユースケースについて本当に考える必要があります。モデルまたはコントローラーから呼び出していますか? その場合は、エラー メッセージを表示しても問題ない可能性があります。ライブラリから呼び出していますか?もしそうなら、おそらく例外をバブルアップさせたほうがよいでしょう。

try{} catch() {}また、グローバルブロックを使用しないでください。代わりに、例外ハンドラをインストールして処理してください。それはよりクリーンで、より意味的に正しいです (anyは、キャッチした例外の処理方法try{}catch{}を知っていることを意味するためです。一方、例外ハンドラーは、処理方法を知らなかったために処理されなかった例外を正確に意味します。

例外は例外的な状況のためのものです。すべてのエラー条件に使用しないでください。ユーザーが短すぎるパスワードを送信した場合、例外をスローせず、検証で処理します。しかし、ハッシュ関数が利用可能であることを期待sha256しているのに利用できない場合、それは例外です。例外は、プログラム エラー (関数への無効な入力など、予期しない状況が発生した場合)、状態エラー (要求されたビューが存在しない場合など、アプリケーションが不明または不安定な状態になった場合) に役立ちます。実行時エラー (ファイルが見つからないエラーなど、実行時にのみ検出できるエラーがアプリケーションで発生した場合)。

于 2011-02-12T14:03:45.970 に答える
2

一般に、他の方法では処理できない例外をエコー/ログするだけで済みます。これは、アプリケーション全体をtryブロック内に配置した場合、エコー/ロギング ロジックを配置する必要がある場所が 1 つしかないことを意味します (つまりcatch、最も外側のブロックに関連付けられたtryブロック)。

一方、アプリケーションを停止せずに例外を処理できる場合 (あなたの例では、これは間違った値ではなくデフォルトの数値を提供している可能性があります)、通常はエコー/ログに記録する必要はありません。

そのような例外をログに記録したい場合 (たとえば、デバッグ用)、アプリケーションにロギング フレームワークが含まれている必要があるため、catchブロック内で次のようなことを行うだけで十分です。

} catch (Exception $e) {
  ExceptionLogger::log($e); //static method == ugly, but it's for simplicity in this example
  // do whatever needs to be done
}

log()上記のメソッドは、ログが有効になっているかどうか、および必要なデータをファイルに保存しているかどうかを確認します。

于 2011-02-12T13:18:32.297 に答える
0

例外の拡張に特化した PHP マニュアルのページ全体があり、そのページには、例外がスローされたファイル/行番号、バックトレースなどを特定する方法に関する多くの情報も記載されています。これは、デバッグに非常に役立つタイプの情報です。

于 2011-02-12T13:22:12.420 に答える