Programing

PHP : 사용자 정의 오류 처리기-구문 분석 및 치명적인 오류 처리

lottogame 2021. 1. 10. 16:44
반응형

PHP : 사용자 정의 오류 처리기-구문 분석 및 치명적인 오류 처리


사용자 지정 오류 처리기를 사용하여 구문 분석치명적인 오류를 어떻게 처리 할 수 있습니까?


간단한 대답 : 할 수 없습니다. 매뉴얼 참조 :

다음 오류 유형은 사용자 정의 함수로 처리 할 수 ​​없습니다.

다른 모든 오류에 대해 다음을 사용할 수 있습니다. set_error_handler()

편집하다:

를 사용하는 것과 관련하여이 주제에 대해 논의가있는 것 같으므로 register_shutdown_function처리의 정의를 살펴보아야합니다. 나에게 오류 처리 란 오류를 포착하고 "좋은"방식으로 반응하는 것을 의미합니다. 사용자 기본 데이터 (데이터베이스, 파일, 웹 서비스 등).

를 사용 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 () 함수가 오류를 처리합니다.

이것은 내가 개발중인 사이트에서 작업하고 있습니다. 아직 프로덕션에서 테스트하지 않았습니다. 그러나 현재 개발 중에 발견 한 모든 오류를 포착하고 있습니다.

각 기능마다 한 번씩 동일한 오류를 두 번 잡을 위험이 있다고 생각합니다. 이것은 shutdownHandler () 함수에서 처리중인 오류가 errorHandler () 함수에 의해 포착 된 경우 발생할 수 있습니다.

TODO :

1-오류를 정상적으로 처리하려면 더 나은 log () 함수를 작업해야합니다. 아직 개발 중이기 때문에 기본적으로 오류를 데이터베이스에 기록하고 화면에 반영하고 있습니다.

2-모든 MySQL 호출에 대해 오류 처리를 구현합니다.

3-내 자바 스크립트 코드에 대한 오류 처리를 구현합니다.

중요 사항 :

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

When I go live, I will change display_errors to 0 to reduce the risk of my users seeing ugly PHP error messages.

I hope this helps someone.


You can track these errors using code like this:

(Parse errors can only be caught if they occur in other script files via include() or require(), or by putting this code into an auto_prepend_file as other answers have mentioned.)

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');

From the PHP.net comments on the page http://www.php.net/manual/en/function.set-error-handler.php

I have realized that a few people here mentioned that you cannot capture parse errors (type 4, E_PARSE). This is not true. Here is how I do. I hope this helps someone.

1) Create a "auto_prepend.php" file in the web root and add this:

<?php 
register_shutdown_function('error_alert'); 

function error_alert() 
{ 
        if(is_null($e = error_get_last()) === false) 
        { 
                mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true)); 
        } 
} 
?> 

2) Then add this "php_value auto_prepend_file /www/auto_prepend.php" to your .htaccess file in the web root.

  • make sure you change the email address and the path to the file.

From my experience you can catch all type of errors, hide the default error message and display an error message of your own (if you like). Below are listed the things you need.

1) An initial/top level script, let us call it index.php where you store you custom error handler functions. Custom error function handlers must stay at the top so they catch errors below them, by "below" I mean in inclued files.

2) The assumption that this top script is error free must be true! this is very important, you cannot catch fatal errors in index.php when your custom error handler function is found in index.php.

3) Php directives (must also be found in index.php) set_error_handler("myNonFatalErrorHandler"); #in order to catch non fatal errors register_shutdown_function('myShutdown'); #in order to catch fatal errors ini_set('display_errors', false); #in order to hide errors shown to user by php ini_set('log_errors',FALSE); #assuming we log the errors our selves ini_set('error_reporting', E_ALL); #We like to report all errors

while in production (if I am not wrong) we can leave ini_set('error_reporting', E_ALL); as is in order to be able to log error, in the same time ini_set('display_errors', false); will make sure that no errors are displayed to the user.

As for the actual content of the two functions I am talking, myNonFatalErrorHandler and myShutdown, I don't put detailed content here in order to keep things simple. In addition the other visitors have given alot of examples. I just show a very plain idea.

function myNonFatalErrorHandler($v, $m, $f, $l, $c){
 $some_logging_var_arr1[]="format $v, $m, $f, ".$err_lvl[$l].", $c the way you like";
 //You can display the content of $some_logging_var_arr1 at the end of execution too.
}

function myShutdown()
{
  if( ($e=error_get_last())!==null ){
      $some_logging_var_arr2= "Format the way you like:". $err_level[$e['type']].$e['message'].$e['file'].$e['line'];
  }
//display $some_logging_var_arr2 now or later, e.g. from a custom session close function
}

as for $err_lvl it can be:

$err_lvl = array(E_ERROR=>'E_ERROR', E_CORE_ERROR=>'E_CORE_ERROR', E_COMPILE_ERROR=>'E_COMPILE_ERROR', E_USER_ERROR=>'E_USER_ERROR', E_PARSE=>'E_PARSE', E_RECOVERABLE_ERROR=>'E_RECOVERABLE_ERROR', E_WARNING=>'E_WARNING', E_CORE_WARNING=>'E_CORE_WARNING', E_COMPILE_WARNING=>'E_COMPILE_WARNING',
E_USER_WARNING=>'E_USER_WARNING', E_NOTICE=>'E_NOTICE', E_USER_NOTICE=>'E_USER_NOTICE',E_STRICT=>'E_STRICT');

The script with parse error is always interrupted and it can not be handled. So if the script is called directly or by include/require, there is nothing you can do. But if it is called by AJAX, flash or any other way, there is a workaround how to detect parse errors.

I needed this to handle swfupload script. Swfupload is a flash that handles file uploads and everytime file is uploaded, it calls PHP handling script to handle filedata - but there is no browser output, so the PHP handling script needs these settings for debugging purposes:

  • warnings and notices ob_start(); at the beginning and store content into session by ob_get_contents(); at the end of the handling script: This can be displayed into browser by another script
  • fatal errors register_shutdown_function() to set the session with the same trick as above
  • parse errors if the ob_get_contents() is located at the end of the handling script and parse error occured before, the session is not filled (it is null). The debugging script can handle it this way: if(!isset($_SESSION["swfupload"])) echo "parse error";

Note 1 null means is not set to isset()

ReferenceURL : https://stackoverflow.com/questions/1900208/php-custom-error-handler-handling-parse-fatal-errors

반응형