【问题标题】:Get all PHP errors/warnings/... that occurred during the current request获取当前请求期间发生的所有 PHP 错误/警告/...
【发布时间】:2016-07-25 07:45:03
【问题描述】:

将指令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()中也不可用

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

【问题讨论】:

  • 是否不能将错误信息写入/附加到错误日志文件中,然后再将其读出?
  • 我多么希望所有错误都是 PHP 中的异常...
  • @SparK:你可以试试php.net/manual/de/function.set-error-handler.php#112881;但我同意:像 Java 中的错误处理会很好,...
  • @vaultboy:这是 HDD I/O - 被认为很慢。

标签: php error-handling


【解决方案1】:

提及您的第一个问题

只要满足以下条件,错误处理仍然有效:

回调函数返回 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() 的 cmets 中有一个很好的例子

另见:

提及您的第二个问题

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

但请记住,

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

【讨论】:

  • 您能否通过出现致命错误来扩展您的代码,...建议Egg
【解决方案2】:

关于 herehere(以及其他)的讨论,second answer on the latter list 使用 set_error_handler()register_shutdown_function() 的组合是一个很好的解决方案。

【讨论】:

    【解决方案3】:

    捕获所有错误(异常和错误)、泵入日志文件并在静态类中记忆的更完整示例;最后您查询静态类以获取错误。

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:
         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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-05
          • 2017-12-16
          相关资源
          最近更新 更多