PHPエラー:分類、例、処理

この記事では、PHP開発者としての道のりで発生する可能性のあるエラー、可能な分類、発生の例、クライアントの応答に対するエラーの影響、および独自のエラーハンドラを記述するための指示に対処する別の試みを示します。

この記事は4つのセクションに分かれています。
  1. エラーの分類。
  2. さまざまなタイプのエラーとさまざまな設定での動作を示す例。
  3. 独自のエラーハンドラを記述します。
  4. 便利なリンク。

エラー分類


すべてのエラーは、条件付きで、いくつかの基準に従ってカテゴリに分類できます。
死亡:

set_error_handler()で定義された関数を使用してエラーをインターセプトする機能:

イニシエーター:

私たちにとって、この記事の枠組みでは、最も興味深い分類は最初の2つの基準に基づいています。これについては以下で説明します。

エラーの例


index.phpのリスト
<?php //     error_reporting(E_ALL | E_STRICT); //     ini_set('display_errors', 'On'); //     require 'errors.php'; 

errors.phpのリスト
 <?php echo "  . <br>"; /* *   (  set_error_handler()) */ // NONFATAL - E_NOTICE // echo $undefined_var; // NONFATAL - E_WARNING // array_key_exists('key', NULL); // NONFATAL - E_DEPRECATED split('[/.-]', "12/21/2012"); // split() deprecated   php 5.3.0 // NONFATAL - E_STRICT // class c {function f(){}} c::f(); // NONFATAL - E_USER_DEPRECATED // trigger_error("E_USER_DEPRECATED", E_USER_DEPRECATED); // NONFATAL - E_USER_WARNING // trigger_error("E_USER_WARNING", E_USER_WARNING); // NONFATAL - E_USER_NOTICE // trigger_error("E_USER_NOTICE", E_USER_NOTICE); // FATAL,     set_error_handler - E_RECOVERABLE_ERROR // class b {function f(int $a){}} $b = new b; $b->f(NULL); // FATAL,     set_error_handler - E_USER_ERROR // trigger_error("E_USER_ERROR", E_USER_ERROR); /* *  (   set_error_handler()) */ // FATAL - E_ERROR // undefined_function(); // FATAL - E_PARSE // parse_error // FATAL - E_COMPILE_ERROR // $var[]; echo "  . <br>"; 

注:スクリプトが完全に機能するには、5.3.0以上のPHPバージョンが必要です。

errors.phpファイルには、考えられるほぼすべてのエラーをトリガーする式が含まれています。 例外は次のとおりです。Zendコアによって生成されたE_CORE_ERROR、E_CORE_WARNING、E_COMPILE_WARNING。 理論的には、実際の仕事で会うべきではありません。
次の表は、さまざまな条件下でのこのスクリプトの動作を示しています( display_errorsおよびerror_reportingディレクティブの値に応じて)。
エラーグループディレクティブ値*サーバーの応答ステータスカスタマーレスポンス**
E_PARSE、E_COMPILE_ERROR ***display_errors = off
error_reporting = ANY
500空の値
display_errors = on
error_reporting = ANY
200エラーメッセージ
E_USER_ERROR、E_ERROR、E_RECOVERABLE_ERRORdisplay_errors = off
error_reporting = ANY
500エラー前のスクリプト出力
display_errors = on
error_reporting = ANY
200エラー前のエラーメッセージとスクリプト出力
致命的でないエラーdisplay_errors = off
error_reporting = ANY
そして
display_errors = on
error_reporting = 0
200すべてのスクリプト出力
display_errors = on
error_reporting = E_ALL | E_STRICT
200エラーメッセージとすべてのスクリプト出力
* ANYはE_ALLを意味します| E_STRICTまたは0。
**クライアントへの回答は、実際のスクリプトの回答と異なる場合があります。 たとえば、errors.phpファイルを含める前の情報の出力は、すべての場合に表示されます。
*** errors.phpファイルで、エラーE_COMPILE_ERRORの例をrequire "missing_file.php";置き換えた場合"missing_file.php"; 、エラーは2番目のグループに分類されます。

上記の表の値は、次のように説明できます。
  1. スクリプトファイルにエラーが存在し、それを「使用不可」状態(正しく処理できない状態)にすると、出力はdisplay_errorsディレクティブの値に応じて空の値またはエラーメッセージのみを返します。
  2. 最初の項目に関係しない致命的なエラーを含むファイル内のスクリプトは、エラー自体が発生するまで通常どおり実行されます。
  3. display_errors = Offのファイルに致命的なエラーが存在する場合、500応答ステータスを示します。
  4. 予想されるように、スクリプト全体を実行する機能のコンテキストでの致命的でないエラーは、パフォーマンスに影響しません。

ネイティブエラーハンドラー


独自のエラーハンドラを作成するには、次のことを知る必要があります。

3番目の点について説明します。register_shutdown_function()で登録した関数は、スクリプトが正常に完了したか、重大な(致命的な)エラーのために中断されたかにかかわらず、実行されます。 error_get_last()関数によって提供される情報を使用して2番目のオプションを明確に決定し、エラーが発生した場合は、独自のエラーハンドラーを実行します。
変更されたindex.phpスクリプトを使用して上記を示します。
 <?php /** *   * @param int $errno   * @param string $errstr    * @param string $errfile  ,     * @param int $errline  ,     * @return boolean */ function error_handler($errno, $errstr, $errfile, $errline) { //      (   "@" error_reporting()  0) if (error_reporting() & $errno) { $errors = array( E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', E_COMPILE_ERROR => 'E_COMPILE_ERROR', E_COMPILE_WARNING => 'E_COMPILE_WARNING', E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', E_USER_NOTICE => 'E_USER_NOTICE', E_STRICT => 'E_STRICT', E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', E_DEPRECATED => 'E_DEPRECATED', E_USER_DEPRECATED => 'E_USER_DEPRECATED', ); //      echo "<b>{$errors[$errno]}</b>[$errno] $errstr ($errfile  $errline )<br />\n"; } //      PHP return TRUE; } /** *     */ function fatal_error_handler() { //       if ($error = error_get_last() AND $error['type'] & ( E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR)) { //   (     ) ob_end_clean(); //    error_handler($error['type'], $error['message'], $error['file'], $error['line']); } else { //  ()     ob_end_flush(); } } //     error_reporting(E_ALL | E_STRICT); //     ini_set('display_errors', 'On'); //    (     ) ob_start(); //     set_error_handler("error_handler"); //  ,       (,   ) register_shutdown_function('fatal_error_handler'); require 'errors.php'; 

混合型のエラーは、独自のエラーハンドラを宣言した後、致命的ではなくなったことを忘れないでください。 さらに、致命的なエラーが発生する前のすべてのスクリプト出力と標準エラーメッセージがリセットされます。

一般に、エラーハンドラーの考慮された例は、そのような処理を扱いませんが、可能性自体を示すだけです。 彼のさらなる行動は、あなたの欲求や要件に依存します。 たとえば、ハンドラーにアクセスするすべてのケースをログに書き込むことができ、致命的なエラーが発生した場合は、さらにリソース管理者に通知します。

便利なリンク


Source: https://habr.com/ru/post/J161483/


All Articles