获取当前请求期间发生的所有PHP错误/警告/ ....

时间:2016-04-05 11:30:47

标签: php error-handling

将指令display_errors设置为true(将error_reporting设置为E_ALL时)会打印在当前请求期间发生的所有错误,bofore将PHP输出撤回。

由于我在PHP代码中发送标题,因此我会收到更多错误(无法在发送内容后发送标题)。

现在我想将错误消息添加到页面的末尾。在那里,我想显示发生的所有错误(直到那时)。不幸的是error_get_last只返回发生的最后一个错误。

我首先想到set_error_handler可能会解决问题,但我担心我的错误记录不再起作用了:

  

重要的是要记住,对于error_types指定的错误类型,标准PHP错误处理程序是完全被绕过的,除非回调函数返回FALSE。

除此之外:

  

使用用户定义的函数无法处理以下错误类型:E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,以及调用set_error_handler()的文件中引发的大部分E_STRICT。

但也许error_get_last()

中也没有

那么有没有办法在输出生成的内容后打印所有错误?

5 个答案:

答案 0 :(得分:5)

herehere(以及其他)进行了讨论,second answer on the latter list使用set_error_handler()register_shutdown_function()混合使用/** * Removes directory and its contents * * @param string $path Path to the directory. */ function _delete_dir($path) { if (!is_dir($path)) { throw new InvalidArgumentException("$path must be a directory"); } if (substr($path, strlen($path) - 1, 1) != DIRECTORY_SEPARATOR) { $path .= DIRECTORY_SEPARATOR; } $files = glob($path . '*', GLOB_MARK); foreach ($files as $file) { if (is_dir($file)) { _delete_dir($file); } else { unlink($file); } } rmdir($path); } 溶液

答案 1 :(得分:5)

参考第一个问题

只要:

,错误处理仍然有效
  

回调函数返回FALSE

function myErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {
    // Do your stuff here, e.g. saving messages to an array

    // Tell PHP to also run its error handler
    return false;
}

存储所有错误编号(在外部数组$error_list中)的一种解决方案可能是:

$error_list = array();

$myErrorHandler = function ($error_level, $error_message, $error_file, $error_line, $error_context) use (&$error_list) {
    $error_list[] = $error_level;
    // Tell PHP to also run its error handler
    return false;
};
// Set your own error handler
$old_error_handler = set_error_handler($myErrorHandler);

另一种方法是使用例外。 function set_error_handler()

的评论中有一个很好的例子

另见:

参考第二个问题

已提及Egg:使用register_shutdown_function()是一种方法,答案https://stackoverflow.com/a/7313887/771077中的代码会向您展示如何。

但请记住,

  • 注册关闭和错误处理函数应该是代码中的第一件事(我曾经在配置文件中遇到错误,但由于我之后注册了错误处理程序,因此无法正确处理错误)。
  • 可能无法正确处理解析错误(请参阅https://stackoverflow.com/a/7313887/771077
  • 中的评论

答案 2 :(得分:2)

Fuller示例捕获所有错误(异常和错误),泵到日志文件并记住静态类;最后,您查询静态类以获取错误。

我对所有项目使用类似的方法来完全控制所有错误。

function customErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
    ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, true);
}

function nullErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
    ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, false);
}

function customExceptionHandler($exception) {
    if (is_a($exception, 'exceptionError')) {
        echo $exception->output();
    } else {
        ErrorHandler(E_ERROR, $exception->getMessage() . '(' . $exception->getCode() . ')', $exception->getFile(), $exception->getLine(), null, true);
    }
}

function nullExceptionHandler($exception) {
    if (is_subclass_of($exception, 'exceptionError')) {
        $exception->output();
    } else {
        ErrorHandler(E_WARNING, $exception->getMessage() . '(' . $exception->getCode() . ')', $exception->getFile(), $exception->getLine(), null, false);
    }
}


function ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, $fatal) {
    $errortype = array (
            E_ERROR              => 'Error',
            E_WARNING            => 'Warning',
            E_PARSE              => 'Parsing Error',
            E_NOTICE             => 'Notice',
            E_CORE_ERROR         => 'Core Error',
            E_CORE_WARNING       => 'Core Warning',
            E_COMPILE_ERROR      => 'Compile Error',
            E_COMPILE_WARNING    => 'Compile Warning',
            E_DEPRECATED         => 'Deprecated',
            E_USER_ERROR         => 'User Error',
            E_USER_WARNING       => 'User Warning',
            E_USER_NOTICE        => 'User Notice',
            E_USER_DEPRECATED    => 'User Deprecated',
            E_STRICT             => 'Runtime Notice',
            E_RECOVERABLE_ERROR  => 'Catchable Fatal Error'
            );


    // Pushed into error log
    if (error_reporting() > 0) {
        $message = ': ' . $errmsg . ' in ' . $filename . ' on line ' . $linenum;
        error_log('PHP ' . $errortype[$errno] . $message);

        errorLogger::log($message);

        if ($fatal) {
            echo $errortype[$errno] . ': ' . $message;
            exit();
        }
    }
}


class errorLogger {

    private static $aErrors = array();

    // ******************* Timing functions *********************************

    public static function log($message) {
        self::$aErrors[] = $message;
    }

    public static function getErrors() {
        return self::$aErrors;
    }

}

用法示例

// Custom error handler. Can cope with the various call mechanisms
$old_error_handler = set_error_handler('nullErrorHandler');
$old_exception_handler = set_exception_handler('nullExceptionHandler');

// Do your stuff
// *
// *
// *
// *
// *

$old_error_handler = set_error_handler('customErrorHandler');   // Set to 'nullErrorHandler' to allow it to continue
$old_exception_handler = set_exception_handler('customExceptionHandler');   // Set to 'nullExceptionHandler' to allow it to continue

// At end
$errors = errorLogger::getErrors();
foreach($errors as $errorMessage) {
    echo $errorMessage;
}

答案 3 :(得分:0)

随时抓取错误并在最后输出消息。

<?php 
$errors = [];
try{    
  // code to test
} catch(\Exception $e) {
  $errors[] = $e->getMessage;
}
try{    
  // next bit of code to test
} catch(\Exception $e) {
  $errors[] = $e->getMessage;
}
...

// display all messages at the end
echo "\n<pre><code>\n";
print_r($errors);
echo "\n</code></pre>\n";

答案 4 :(得分:-1)

 ini_set('display_errors', 1);
 ini_set('display_startup_errors', 1);
 error_reporting(E_ALL);

  or
   set your php.ini with this line:
   display_errors=on