カスタムエラーハンドラを使用して解析&致命的エラーを処理するにはどうすればよいですか?
簡単な答え:できません。 manual を参照してください:
次のエラータイプは、ユーザー定義関数では処理できません:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING、およびset_error_handler()が呼び出されるファイルで発生するE_STRICTのほとんど。
他のすべてのエラーについては、set_error_handler()
を使用できます
編集:
register_shutdown_function
の使用に関して、このトピックに関するいくつかの議論があるように思えるので、処理の定義を確認する必要があります。ユーザーおよび基になるデータ(データベース、ファイル、Webサービスなど)にとって「いい」です。
register_shutdown_function
を使用すると、呼び出されたコード内からエラーを処理することはできません。つまり、エラーが発生した時点でコードが機能しなくなります。ただし、ホワイトページの代わりにエラーメッセージをユーザーに表示することはできますが、たとえば、失敗する前にコードで実行したことをロールバックすることはできません。
実際には、解析エラーと致命的なエラーを処理できます。 set_error_handler()で定義したエラーハンドラー関数が呼び出されないのは事実です。それを行う方法は、register_shutdown_function()でシャットダウン関数を定義することです。これが私のウェブサイトで働いていることです:
ファイルprepend.php(このファイルはすべてのphpスクリプトに自動的に追加されます)。ファイルをPHPに追加するためのヒントについては、以下を参照してください。
set_error_handler("errorHandler");
register_shutdown_function("shutdownHandler");
function errorHandler($error_level, $error_message, $error_file, $error_line, $error_context)
{
$error = "lvl: " . $error_level . " | msg:" . $error_message . " | file:" . $error_file . " | ln:" . $error_line;
switch ($error_level) {
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_PARSE:
mylog($error, "fatal");
break;
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
mylog($error, "error");
break;
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_WARNING:
mylog($error, "warn");
break;
case E_NOTICE:
case E_USER_NOTICE:
mylog($error, "info");
break;
case E_STRICT:
mylog($error, "debug");
break;
default:
mylog($error, "warn");
}
}
function shutdownHandler() //will be called when php script ends.
{
$lasterror = error_get_last();
switch ($lasterror['type'])
{
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_PARSE:
$error = "[SHUTDOWN] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line'];
mylog($error, "fatal");
}
}
function mylog($error, $errlvl)
{
...do whatever you want...
}
PHPは、スクリプトのいずれかでエラーをキャッチすると、errorHandler()関数を呼び出します。エラーによってスクリプトがすぐにシャットダウンされる場合、エラーは関数shutdownHandler()によって処理されます。
これは、開発中のサイトで機能しています。実稼働ではまだテストしていません。しかし、現在、開発中に見つかったすべてのエラーをキャッチしています。
同じエラーを各機能で1回ずつ、2回キャッチするリスクがあると思います。これは、関数shutdownHandler()で処理しているエラーが関数errorHandler()でもキャッチされた場合に発生する可能性があります。
TODO:
1-エラーを適切に処理するために、より良いlog()関数で作業する必要があります。私はまだ開発中なので、基本的にデータベースにエラーを記録し、画面にエコーします。
2-すべてのMySQL呼び出しにエラー処理を実装します。
3-JavaScriptコードのエラー処理を実装します。
重要な注意事項:
1-php.iniで次の行を使用して、上記のスクリプトをすべてのphpスクリプトに自動的に追加します。
auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"
それはうまく機能します。
2-E_STRICTエラーを含むすべてのエラーをログに記録して解決しています。きれいなコードを開発することを信じています。開発中、私のphp.iniファイルには次の行があります。
track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0
ライブに移行したら、display_errorsを0に変更して、ユーザーがusersいPHPエラーメッセージを表示するリスクを軽減します。
これが誰かの助けになることを願っています。
次のようなコードを使用して、これらのエラーを追跡できます。
(解析エラーは、include()
またはrequire()
を介してotherスクリプトファイルで発生した場合、またはこのコードをauto_prepend_file
他の回答が述べているように。)
function shutdown() {
$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if ($isError){
var_dump ($error);//do whatever you need with it
}
}
register_shutdown_function('shutdown');
ページのPHP.netコメントから http://www.php.net/manual/en/function.set-error-handler.php
ここでは、解析エラー(タイプ4、E_PARSE)をキャプチャできないと言っている人がいることに気付きました。本当じゃない。これが私のやり方です。これが誰かの助けになることを願っています。
1)Webルートに「auto_prepend.php」ファイルを作成し、これを追加します。
<?php
register_shutdown_function('error_alert');
function error_alert()
{
if(is_null($e = error_get_last()) === false)
{
mail('[email protected]', 'Error from auto_prepend', print_r($e, true));
}
}
?>
2)次に、この「php_value auto_prepend_file /www/auto_prepend.php」をWebルートの.htaccessファイルに追加します。
- メールアドレスとファイルへのパスを必ず変更してください。
解析エラーのあるスクリプトは常に中断され、処理できません。したがって、スクリプトが直接またはinclude/requireによって呼び出された場合、何もできません。しかし、AJAX、フラッシュ、またはその他の方法で呼び出された場合、(解析エラーを検出する方法の回避策があります。
swfupload スクリプトを処理するためにこれが必要でした。 Swfuploadは、ファイルのアップロードを処理するフラッシュであり、ファイルがアップロードされるたびに、PHPスクリプトを処理してfiledataを処理します。ただし、ブラウザ出力がないため、PHP =スクリプトを処理するには、デバッグのために次の設定が必要です。
if(!isset($_SESSION["swfupload"])) echo "parse error";
注1null
は_is not set
_からisset()
を意味します