PHPエレガントなキャプチャ処理エラー--E_PARSE/E_ERROR


開発で使用されたフレームワークは,ほとんどが文法的な誤り,すなわちParse Error(syntax error)E_を優雅に再現できる.PARSE,このエラーはユーザコードの最下位レベル向けのエラーとしてどのようにキャプチャされますか?
次に、E_をキャプチャする方法について説明します.PARSE & E_ERRORエラー、ここで私はわざとE_をPARSEが間違って上位に置いたのは、E_PARSEは,ユーザ向けスクリプトの1番目のエラーであり,必然的に最初に発生する.そしてE_ERROR & E_WARNING & E_NOTICE ....クラスのランタイムエラー.
PHPエラーレベル
#                   try ... catch ...   
E_PARSE                                        
E_ERROR                                   

#    set_error_handler     
E_WARNING                       
E_NOTICE                                
E_DEPRECATED                 

# Zend Engine                        try ... catch ...        
E_CORE_ERROR
E_CORE_WARNING
E_COMPILE_ERROR
E_COMPILE_WARNING

#             trigger_error       set_error_handler     
E_USER_ERROR                         
E_USER_WARNING
E_USER_NOTICE
E_USER_DEPRECATED

#       (           )
E_STRICT         try ... catch ...    set_error_handler
E_RECOVERABLE_ERROR

まず問題コードを見てみましょう
無邪気な考え
1、すべてのエラーレポートをクローズしたい

PHPは依然として自身のエラーメカニズムを使用してエラーを報告し、原因は簡単である:文法解析--解釈運転--終了終了終了終了.スクリプトの基本的な構文に問題がある場合、Zend Engine自身が実行を終了し、Parse ERRORエラーメッセージを表示します.実行ユーザコード、すなわちerror_はまだ解釈されていないReporting(0)はまだZend Engineでランタイム環境の設定をしていません.
2、set_を使いたいerror_handlerスナップエラー

依然として理想的な結果が得られない.
まず、このコードも解析の段階でエラーを報告して、Parse Errorは直接退出して、まだ本当にset_を実行していませんerror_handler().
公式原語解説:
スクリプトの実行前(ファイルのアップロードなど)にエラーが発生した場合、カスタムエラーハンドラは登録されていないため呼び出されません.
それに、一歩下がって、set_error_handlerはユーザレベルエラーE_をカスタマイズするために使用されますUSER_ERROR & E_USER_WARNING & E_USER_NOTICE & E_USER_DEPRECATEDと一部ランタイムシステムエラーE_WARING & E_NOTICE & E_DEPRECATEDのキャプチャ、すなわち構文解析エラーE_PARSE(Parse Error)はそれを捕獲することはできない.
公式原語解説:
次のレベルのエラーは、ユーザー定義関数では処理できません.E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING、およびset_を呼び出していますerror_handler()関数が存在するファイルで生成されるほとんどのE_STRICT.
定義したset_error_handlerのhandlerは最後にfalseを返し、このエラー情報はPHPの標準エラーハンドラで処理され続けます:error_を介してReportingのレベル設定、この書き込みエラーログの書き込みエラーログ(log_errors&error_log)
公式原語解説:
重要なのはerror_を覚えることですtypesで指定したエラータイプは、コールバック関数がFALSEを返さない限り、PHP標準エラーハンドラを迂回します.
注意、set_error_handlerは独自のキャプチャレベルを持ち、デフォルトE_ALL | E_STRICTですが、上記のいくつかのレベルに出て、errorを受けません.Reporting()設定のレベルの影響は、error_reporting(0),set_error_handlerは依然として対応するエラーをキャプチャすることができます.
幾つかの問題.
1、                      (E_PARSE & E_ERROR) ?   laravel     whoops 
2、E_PARSE & E_ERROR          ?
3、          E_PARSE & E_ERROR         ,           
error_reporting()           ?

適切なレベル設定がある以上、キャプチャ可能であることを説明します.まず簡単に説明します.E_ERRORのスナップは実は簡単で、E_PARSEのキャプチャは,PHP解析とスクリプト実行のメカニズムフローに関連する説明と理解が必要である.
PHPの基本的な動作メカニズムを分析する
実はとても簡単で、一度見て理解しました(以下のいくつかの運行メカニズムの用語は正確ではないかもしれませんが、大物に見逃してください.すべてはみんなが理解しやすいようにしています).
1、phpは実行ユーザーコードを解釈する時、メインスクリプトをロードポイントとして、Zend Engineはまずそれに対して文法解析(Parse)を行います.ここで必ず理解してください.Zend Engineはこの時スクリプトの文法を解析して、スクリプトの中のいかなるini設定もそれに対して無効です(まだロード実行初期化を説明していません)、だからあなたが設定したerror_reporting, display_errors, set_error_handler.構文解析に誤りがない場合にのみ、Zend Engineがスクリプトの読み込みと解釈を開始し、スクリプトのパラメータ設定項目の一部が有効になります.
2、phpに//リンク依存ライブラリがない--コンパイル--実行//説.phpがプライマリ・スクリプトに依存を導入する場合、Zend Engineはプライマリ・スクリプトの構文解析時に依存も解析にロードしません.Zend Engineは現在のマスタースクリプトのみを構文解析し、解析が通過すると、「依存」にParse Errorがある場合でも、実際にロードコマンドが実行されるまで解析-解釈-実行をロードするユーザーコードの解釈を開始します.
そこで、まずParse OKのコンテナを構築し、Zend Engineのいくつかのランタイム構成を初期化します.例えば、エラーレポートを閉じると、その後E_があっても、ランタイム全体がエラーレポートのコンテキストを閉じることができます.PAESE & E_ERRORでもエラーメッセージは表示されません.しかし、私たちの目的は捕まえることです.
tryを使用...catchキャプチャE_PARSE & E_ERROR

解析プロセス:
1:error_reporting(E_ALL);        
2:echo "this is main script" . PHP_EOL;        
3:require_once __DIR__ . '/lib.php';         
(  :           lib.php        )
4:echo "hello world!" . PHP_EOL;       

解析完了、構文通過、解釈実行開始
プロセスの実行:
1:error_reporting(E_ALL);                    ,             
2:echo "this is main script" . PHP_EOL;       
3:require_once __DIR__ . '/lib.php';           ?          -       
4:echo "hello world!" . PHP_EOL;    lib.php      -                 

気づいたのか?lib.phpがロードされる前にmain scriptのいくつかの実行時のパラメータ設定が有効になりました.例えば、ここのerror_reporting(E_ALL),lib.php解析/解釈実行時はすでにエラーアラートレベルをカスタマイズしたコンテキストにあり、Zend Engineは私たちが設定したエラーアラートレベルに基づいてlibに対して実行する.phpをロードします.この時点でE_がわかるPARSE & E_ERRORエラーはユーザーによって設定できる意味でしょう.
つまり、まず、必要なユーザー設定をZend Engineに渡して実行時コンテキストを初期化し、その後、実行されたユーザーコードをロードすると、このコンテキストで実行され、その後のビジネスロジックが実行されます.
合理的なコード組織構造
例:1、すべてのエラーレポートを閉じる
main.js

lib.js

ではlib.phpのエラーは報告されません.mainがlibのロード時にZend Engineにerror_を送信したためです.reporting(0); のコマンドなので、libのParse Errorは報告されません.しかし、これは私たちが望んでいるものではありません.私たちは捕獲しなければなりません.
2、キャプチャシステムレベルエラーE_PARSE & E_ERROR
まず、実行時にZend Engineをロードして初期化し、実行を開始するコンテナが必要です.tryを使って...catchスナップエラー:

出力結果:
ParseError::__set_state(array(
   'message' => 'syntax error, unexpected end of file, expecting \',\' or \';\'',
   'string' => '',
   'code' => 0,
   'file' => '...\lib.php',
   'line' => 2,
   'trace' => array (),
   'previous' => NULL,
))

これにより、Parse Errorエラーを優雅に入手し、パッケージしてユーザーに出力すればよい.
Parse Errorはユーザレベルの最上位レベルのエラーといえるが,Parse Errorはユーザスクリプトを終了する.
そして私たちはE_に出会う可能性がありますERROR & E_WARNING & E_NOTICE & E_DEPRECATEDなどは、以下の通り.

実行結果
Error::__set_state(array(
    'message'  => 'Call to undefined function func_not_exists()',
    'string'   => '',
    'code'     => 0,
    'file'     => '...main.php',
    'line'     => 47,
    'trace'    => array(),
    'previous' => null,
))

以上のように、構文に問題はないので、Parse Errorはありません.Zend Engineは、存在しないメソッドが呼び出されたため、スクリプト解釈の実行をロードし始めました.ERRORがトリガーされて捕獲されました.
完全なエラー収集
try ... catchはE_をキャプチャできますPARSE & E_ERROR
set_error_handlerはE_をキャプチャできますWARNING & E_NOTICE & E_DEPRECATED & E_USER_*
両方を組み合わせると、ほとんどのユーザーコードレベルのエラーをキャプチャできます.

注意set_error_ハドルとtry...catchはエラーキャプチャ後もプログラムを実行し続け、すぐに終了することはありません.
まとめ
E_ERROR & E_PARSE使用try...catchキャプチャ
E_WARNING & E_NOTICE & E_DEPRECATED & E_USER_* set_の使用error_handlerスナップ
対応する処理をしていない場合、エラー情報はPHP標準エラー処理フローに提出され、error_reporting/display_errors/log_errors/error_logの設定で処理します.