2010-12-10 22 views
31

the comment on this answerによれば、set_error_handler()を使用してキャッチできないshutdown functionによって致命的なエラーをキャッチすることが可能です。register_shutdown_function()を使用してPHPで致命的なエラーを処理する

しかし、致命的なエラーやスクリプトの終了によるシャットダウンが発生したかどうかを判断する方法がわかりませんでした。

また、シャットダウン機能ではデバッグバックトレース機能が無効になっているようで、致命的なエラーが発生したスタックトレースを記録するのは無駄です。

私の質問は、適切なバックトレースを作成する機能を維持しながら、致命的なエラー(特に定義されていない関数呼び出し)に反応する最良の方法は何ですか?

答えて

54

これは私の作品:

function shutdown() { 
    $error = error_get_last(); 
    if ($error['type'] === E_ERROR) { 
     // fatal error has occured 
    } 
} 

register_shutdown_function('shutdown'); 

spl_autoload_register('foo'); 
// throws a LogicException which is not caught, so triggers a E_ERROR 

はしかし、あなたはおそらくすでにそれを知っているが、念のために:あなたは、どのような方法でE_ERRORから回復することはできません。バックトレース用として、あなたは... :(致命的なエラー、特に未定義の関数エラーのほとんどのケースでは、あなたが本当にそれを必要としないことはできません

。それが発生したファイル/行をされてピンポイント

+0

GREAT SNIPPET! "; $ error ['line']。"] \ r \ n ";' UPVOTED:) –

7

register_shutdown_functionで致命的なエラーと適切なアプリケーションシャットダウンを区別する方法の1つは、プログラムの最後の行として定数を定義し、定数が定義されているかどうかを確認することです。

function fatal_error() { 
if (! defined(PROGRAM_EXECUTION_SUCCESSFUL)) { 
     // fatal error has occurred 
    } 
} 

register_shutdown_function('fatal_error'); 

define('PROGRAM_EXECUTION_SUCCESSFUL', true); 

プログラムが終了すると、致命的なエラーに遭遇していないので、定数が定義されていれば関数を実行しないことがわかります。

error_get_last()はデバッグする必要がある致命的なエラーに関するすべての情報を含む配列ですが、前述したようにバックトレースはありません。

一般に、あなたのPHPプログラムが(例外ではなく)致命的なエラーを検出した場合、問題を見つけて修正できるように、プログラムが爆発的になります。 register_shutdown_functionは、エラー報告をオフにするプロダクション環境に便利ですが、バックグラウンドでエラーをログに記録して対応できるようにしたいと考えています。また、このようなエラーが発生した場合に、関数を使用してフレンドリーなHTMLページにユーザーを誘導することで、空白のページを提供するだけでなく、

4

現在error_handlerはメソッドを取得するだけで素敵なトリック=)

<?php 
register_shutdown_function('__fatalHandler'); 
function __fatalHandler() 
{ 
    $error  = error_get_last(); 

    //check if it's a core/fatal error, otherwise it's a normal shutdown 
    if($error !== NULL && $error['type'] === E_ERROR) { 
     //Bit hackish, but the set_exception_handler will return the old handler 
     function fakeHandler() { } 
     $handler = set_exception_handler('fakeHandler'); 
     restore_exception_handler(); 
     if($handler !== null) { 
      call_user_func($handler, new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line'])); 
     } 
     exit; 
    } 
} 
?> 

また、私はあなたが

<?php 
ini_set('display_errors', false); 
?> 

を呼び出す場合、PHPはそれ以外の場合は、エラーをエラーを表示停止していることに注意することwan'tテキストはエラーハンドラの前にクライアントに送信されます

-1

私はこれに "ob_start"を使用します。

function fatal_error_handler($buffer) { 
    if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs)) { 
     //Your code 
    } 
    return $buffer; 
} 
ob_start("fatal_error_handler"); 
+0

これは、パラメータが渡されることを示唆していますが、regexを使用することはあまり効率的ではありません。受け入れられた答えはより明確で効率的です。 – pcnate

関連する問題