2008-08-31 12 views
11

私は飛躍しています:私のPHPスクリプトはすべて正常に失敗します! set_error_handlerは動作しませんどのように私はそれが働きたい

は、少なくとも、それは私が、私は(事実上)のtry ... catchステートメント内のすべての単一の行をラップしたくないために...

望んでいるものですので、私は私の最善の策は、にあると思います私のファイルの先頭にカスタムエラーハンドラを作成します。

私は練習のページにそれをテストしています:

function customError($level,$message,$file,$line,$context) { 
    echo "Sorry, an error has occured on line $line.<br />"; 
    echo "The function that caused the error says $message.<br />"; 
    die(); 
} 

set_error_handler("customError"); 

echo($imAFakeVariable); 

これは戻って、正常に動作します:

Sorry, an error has occured on line 17. The function that caused the error says Undefined variable: imAFakeVariable.

ただし、この設定は未定義の機能は動作しません。

function customError($level,$message,$file,$line,$context) { 
    echo "Sorry, an error has occured on line $line.<br />"; 
    echo "The function that caused the error says $message.<br />"; 
    die(); 
} 

set_error_handler("customError"); 

imAFakeFunction(); 

これが返されます。

Fatal error: Call to undefined function: imafakefunction() in /Library/WebServer/Documents/experimental/errorhandle.php on line 17

はなぜ私のカスタムエラーハンドラが未定義の関数をキャッチされていませんか?これが原因となる他の問題はありますか?

答えて

9

set_error_handlerのコードでエラーを処理するように設計されています。これは、set_error_handlerユーザーエラー関数trigger_errorによってスローされたエラーを報告する方法であるためです。これらのエラーは黙っ例えば、ファイルに報告しなければならないのに本当に

"The following error types cannot be handled with a user defined function: E_ERROR , E_PARSE , E_CORE_ERROR , E_CORE_WARNING , E_COMPILE_ERROR , E_COMPILE_WARNING , and most of E_STRICT raised in the file where set_error_handler() is called."

This is not exactly true. set_error_handler() can't handle them, but ob_start() can handle at least E_ERROR .

<?php 

function error_handler($output) 
{ 
    $error = error_get_last(); 
    $output = ""; 
    foreach ($error as $info => $string) 
     $output .= "{$info}: {$string}\n"; 
    return $output; 
} 

ob_start('error_handler'); 

will_this_undefined_function_raise_an_error(); 

?> 

はしかし、私はあなたを助けるかもしれない手動でこのコメントを見つけました。うまく行けば、あなたのプロジェクトに多くのE_PARSEのエラーが発生することはありません! :-)

一般的なエラーの報告については、例外を守ってください(私のMVCシステムと結びつけるのが有益です)。あなたは非常に汎用性の高い例外を構築して、ボタンを使用してオプションを提供し、何が間違っているかをユーザーに知らせるための説明を追加することができます。

1

Why isn't my custom error handler catching undefinedd functions? Are there other problems that this will cause?

私は、定義されていない関数エラーは他のエラータイプとは異なる実行パスを通ると言います。おそらく、PHPの設計者は、PHPが何らかの形で設計されているかどうかを除いて、もっとあなたに伝えることができます。

スクリプトを正常に機能させずにPHPスタイルにしたい場合は、ページ全体を関数に入れて、try..catchブロック内で呼び出してみてください。 documentation(強調追加)から

1

The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

未定義の関数を呼び出すとは、このように、それはエラーコールバック(またはそのことについては例外ハンドラによって)によって処理することができない、E_ERRORをトリガします。あなたができることはすべてerror_reportingを0に設定することです。

PS、あなた自身のエラーハンドラを動かしているなら、@演算子を正しく扱うように注意してください。ドキュメント(強調追加)から:E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE

It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator.

6

私はあなたが例えばregister_shutdown_function

を使用する必要があると思います:私は同様の問題に直面していたとして、私が今日発見した

register_shutdown_function(array($this, 'customError'));. 

    function customError() 
    { 

    $arrStrErrorInfo = error_get_last(); 

    print_r($arrStrErrorInfo); 

    } 
0

非常に興味深いです。 - あなたは、以下の使用している場合、それはあなたのカスタムエラーハンドラ関数/メソッドでエラーをキャッチします:

ini_set('display_errors', 'Off'); 
error_reporting(-1); 

set_error_handler(array("Cmd\Exception\Handler", "getError"), -1 & ~E_NOTICE & ~E_USER_NOTICE); 

に「はdisplay_errors」を設定することで、あなたはまだキャッチハンドラでそれらをキャッチすることができます「OFF」。

0

私はしばらくの間エラー処理を行ってきましたが、ほとんどの場合はうまくいくようです。

function fatalHandler() { 
    global $fatalHandlerError, $fatalHandlerTitle; 

    $fatalHandlerError = error_get_last(); 

    if($fatalHandlerError !== null) { 

     print($fatalHandlerTitle="{$fatalHandlerTitle} | ".join(" | ", $fatalHandlerError). 
       (preg_match("/memory/i", $fatalHandlerError["message"]) ? " | Mem: limit ".ini_get('memory_limit')."/peak ".round(memory_get_peak_usage(true)/(1024*1024))."M" : "")."\n". 
         "GET: ".var_export($_GET,1)."\n". 
         "POST: ".var_export($_POST,1)."\n". 
         "SESSION: ".var_export($_SESSION,1)."\n". 
         "HEADERS: ".var_export(getallheaders(),1)); 
    } 

    return $fatalHandlerTitle; 
} 

function fatalHandlerInit($title="phpError") { 
    global $fatalHandlerError, $fatalHandlerTitle; 

    $fatalHandlerTitle = $title; 
    $fatalHandlerError = error_get_last(); 

    set_error_handler("fatalHandler"); 
} 

ここで私はメモリが使い果たされたときに毎回それを報告しないという問題があります。どのくらいのメモリが使用されているかによって異なります。 無限ループで大容量のファイルを読み込むためにスクリプトを実行しました(約6.6Mのメモリが必要です)。 SETUP1:

ini_set('memory_limit', '296M'); 

fatalHandlerInit("testing"); 

$file[] = file("large file"); // copy paste a bunch of times 

この場合は、私がレポートするエラーを取得し、それは45のファイルのロードに死にます。

セットアップ2 - 同じですが変更: ini_set( 'memory_limit'、 '299M');

今回はエラーが発生せず、カスタムエラー機能も呼び出されません。スクリプトは同じ行で終了します。

誰にも手掛かりがあり、それを回避する方法はありますか?

関連する問題