みなさんこんにちは!
Yiiのエラー処理プロセスは、このフレームワークを使用した最初の日から完全に透過的ではありませんでした。 特別なセクション
Error Handlingのドキュメントの存在にもかかわらず。 どのような場合にどのビューが使用されるか、Ajaxまたはデバッグモードがどのように影響するか、なぜerrorActionが必要か、例外を処理するときの違いは何ですか?
その結果、ドキュメントとフレームワークのソースコードを掘り下げた後、エラー処理のための視覚的なスキームを描きました。
カットの下で、スキーム自体とそれにいくつかのコメント。
0.エラーレベル
そのため、デフォルトでは、Yiiは
警告および
通知エラー、および
キャッチされ
なかった例外のみを処理します。 致命的なエラーを処理するには、register_shutdown_functionを使用します(詳細は記事の最後にあります)。
1.行こう!
警告が発生した場合、またはキャッチされなかった例外が発生した場合、2つの定数がそれに応じて設定されていれば、Yiiはそれらを処理します。
YII_ENABLE_ERROR_HANDLER = true YII_ENABLE_EXCEPTION_HANDLER = true
同様のシナリオでYiiでエラーと例外の両方が処理されます。 しかし、私が言及する特定の違いがあります。

2.ロギング
まず、エラーまたは例外情報がログに書き込まれます
-Yii :: log()関数。
3.イベントコール
次に、
onError (
onException )イベントが
発生します。 これらのイベントにユーザー定義のハンドラーがある場合、呼び出され、必要なアクションを実行し、イベントのさらなる処理を停止できます(
event-> handled =
trueを設定することにより)。 次のようにハンドラーを切断できます。
$app->onError=function($event) { ... }
またはattachEventHandler()メソッドを介して。
4.接続ErrorHandler
イベント処理が続行する場合(
event-> handled =
false )、errorHandler yiiアプリケーションの標準コンポーネントが機能します(デフォルトでは常にnullではありません)。 対応する
handleError()または
handleException()メソッドを呼び出します。 これらの同様の方法の中で、エラーと例外(Yii 1.1.9の現在のバージョンで利用可能)の間に重要な違いがあります:
- handleError()で、要求タイプ(ajaxかどうか)およびアプリケーションモード(定数YII_DEBUG)がチェックされます
- handleException()で、例外のタイプ(CHttpExceptionまたはCException)およびアプリケーションモード(定数YII_DEBUG)がチェックされます
これに応じて、最も単純なhtml-error出力がapp-> displayError()経由で呼び出されるか、ErrorHandlerコンポーネントのトリッキーな
render()関数が呼び出されます。
以前は、ajaxのチェックもhandleException()で行われていましたが、1.1.9で削除されたため、ajaxリクエスト(たとえば、jsonを返す)の例外を処理しやすくなりました。
5. ErrorHandlerでのトリッキーなレンダリング
ErrorHandler-> render()関数を「tricky」と呼びます。これは、コントローラーの通常のレンダリングとは少し異なる動作をするためです。
- YII_DEBUG = trueの場合、 「exception」パラメーターを使用して起動されます。
「exception.php」をレンダリング-エラーと例外の両方の詳細なデバッグ情報を表示します - YII_DEBUG = falseでCHttpExceptionの場合、 「error」パラメーターでスローされます。
a。 errorActionが設定されている場合、それが実行され、カスタムエラー表示が表示されます
b。 errorActionが設定されていない場合、ビューerrorXXX.phpの呼び出しを試みます。 ここで、 XXXはhttp例外コードです(エラーの場合は常に500)
c。 ビューerrorXXX.phpが見つからない場合、ユニバーサルerror.phpを呼び出そうとします
ビューは次の場所で順番に検索されます。
1.テーマ/ ThemeName /ビュー/システム
2.保護/ビュー/システム
3.フレームワーク/ビュー
6.カスタムエラー表示
errorActionが設定されている場合(たとえば、configの "site / error")、このメソッドは、実稼働モードでのカスタム表示エラーと例外の表示に使用されます。 ajaxリクエストと非ajaxリクエストについては、異なる結論を出すのが便利です。 また、ここでは、
ビュー/サイト/error.php (ページの完全なhtmlコードを含む
views / system / errorXXX.phpとは異なり
ます)を介して、アプリケーションの一般的なレイアウトで出力を実行できることに注意してください。
あとがき:致命的なエラー処理
しかし、致命的なエラーはどうでしょうか?
register_shutdown_functionによるインターセプトは、現在Yiiでは実装されていません。 現在プロジェクトで使用しているソリューションは次のとおりです。
1.アプリケーションを初期化するときに、シャットダウンハンドラーを登録します
2.ハンドラーで、
error_get_last()を使用してエラーとそのレベルを確認します。 エラーがすでに処理されている場合、NULLが返されます
3.
app-> handleError()で処理メカニズム全体を実行します。つまり、 サーキットの始まりに近い
error_get_last()を使用する場合、この関数は演算子の前のerror_reportingディレクティブと@記号を無視することに注意することが重要です。 表示されず、処理されないE_NOTICEを含めることができます(たとえば、セッションの実行中に@session_start()を呼び出します)。
したがって、ハンドラーでは、致命的なエラーのみをチェックします。
また、
errorAction = nullを設定し
ます。次に、図から明らかなように、システムビュー
error.phpが表示されます。これは、エラーが繰り返される可能性が高い別のコントローラーアクションを実行するよりも信頼性が高くなります。
class WebApplication extends CWebApplication { protected function init() { register_shutdown_function(array($this, 'onShutdownHandler')); parent::init(); } public function onShutdownHandler() {
おわりに
私の意見では、Yiiのエラー処理プロセスはそれほど単純ではありませんが、非常に柔軟性があります。 私はあなたのコメントとアドバイスを聞いてうれしいです。
ご清聴ありがとうございました!
UPD:スキーム
をPDF形式で投稿しました