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


Get all PHP errors/warnings/... that occurred during the current request

将指令display_errors设置为true(同时将error_reporting设置为E_ALL)会在返回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() 中也不可用

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

提到您的第一个问题

只要

回调函数返回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);

另一种方法是使用Exceptions。函数set_error_handler()的注释中有一个很好的例子

另请参阅:

  • PHP中的全局变量是否被认为是不好的做法?如果是,为什么
  • PHP:使用外部计算变量的回调函数

关于您的第二个问题:

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

但请记住,

  • 注册关闭和错误处理函数应该是代码中的第一件事(我傻瓜曾经在配置文件中遇到过一个错误,但处理不正确,因为我后来注册了错误处理程序)
  • 分析错误可能无法正确处理(请参阅中的注释https://stackoverflow.com/a/7313887/771077)

这里和这里(以及其他地方)都有关于这一点的讨论,后一个列表中的第二个答案使用set_error_handler()register_shutdown_function()的组合是一个很好的解决方案。

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;
}

在执行过程中捕获错误并在最后输出消息。

<?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";
 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