youssef/error

让处理和调试 PHP 错误变得不那么糟糕。

v0.1 2016-11-14 20:37 UTC

This package is not auto-updated.

Last update: 2024-09-23 12:32:16 UTC


README

让处理和调试 PHP 错误变得不那么糟糕。 基于 kuria/error (https://github.com/kuria/error)

目录

功能

  • 调试和非调试模式
  • 将 PHP 错误(警告、通知等)转换为异常
    • 尊重全局 error_reporting 设置
  • 处理未捕获的异常和致命错误(包括解析错误)
  • CLI 错误屏幕(将错误写入 STDERR)
  • Web 错误屏幕(为网页浏览器渲染错误)
    • 非调试模式
      Web error screen in non-debug mode
      • 简单的错误信息
      • 不透露任何内部信息
      • 不使用 "oops" 等词汇的任何变体
    • 调试模式
      Web error screen in debug mode
      • 文件路径和行号
      • 高亮代码预览
      • 堆栈跟踪
      • 参数列表
      • 变量上下文
      • 输出缓冲区(也可以以 HTML 的形式显示)
      • 纯文本跟踪(用于复制粘贴)
  • 可利用的事件系统
    • 实现日志记录
    • 有条件地抑制或强制错误
    • 更改或添加错误屏幕内容

要求

  • PHP 5.3 或更高版本

使用示例

use Kuria\Error\ErrorHandler;

$debug = true; // true during development, false in production
error_reporting(E_ALL | E_STRICT); // configure the error reporting

$errorHandler = new ErrorHandler($debug);
$errorHandler->register();

// trigger an error to see the error handler in action
echo $invalidVariable;

事件系统

  • 使用 kuria/event 库实现
  • 错误处理器在处理错误时触发事件
  • 两个内置的错误屏幕实现都在渲染时触发事件

错误处理器事件

可能由 ErrorHandler 类发出的事件

error

  • 当发生 PHP 错误时发出
  • 参数
    1. 对象 $exception
      • ErrorExceptionKuria\Error\ContextualErrorException 的实例
    2. bool $debug
    3. bool &$suppressed
      • 对错误抑制状态的引用
      • 错误可以通过当前的 error_reporting 配置或其他事件处理器来抑制

fatal

  • 当正在处理未捕获的异常或致命错误时发出
  • 参数
    1. 对象 $exception
    2. bool $debug
    3. FatalErrorHandlerInterface &$handler
      • 对当前致命错误处理器的引用

emerg

  • 当在致命错误处理期间抛出其他异常时发出
  • 此时将抛出更多未捕获的异常或致命错误,将终止脚本
  • 参数
    1. 对象 $exception
    2. bool $debug

Web 错误屏幕事件

可能由 WebErrorScreen 类发出的事件

render

  • 非调试模式 下渲染时发出
  • 参数
    1. array &$view
      • title: 用于 <title>
      • heading: 用于 <h1>
      • text: 默认段落的文本内容
      • extras: 主要部分之后的自定义 HTML
        • 使用 .= 追加到此处
    2. 对象 $exception
    3. string|null $outputBuffer
    4. WebErrorScreen $screen

render.debug

  • 调试模式 下渲染时发出
  • 参数
    1. array &$view
      • title: 用于 <title>
      • extras: 主要部分之后的自定义 HTML
        • 使用 .= 追加到此处
    2. 对象 $exception
    3. string|null $outputBuffer
    4. WebErrorScreen $screen

layout.css

  • 当输出 CSS 样式时发出
  • 参数
    1. string &$css
      • 对 CSS 输出的引用
      • 可以追加或替换它
    2. bool $debug
    3. WebErrorScreen $screen

layout.js

  • 当输出 JavaScript 代码时发出
  • 参数
    1. string &$js
      • JavaScript 输出引用
      • 可以追加或替换它
    2. bool $debug
    3. WebErrorScreen $screen

CLI 错误屏幕事件

CliErrorScreen 类可能发出的事件

render

  • 在非调试模式下渲染时发出
  • 参数
    1. array &$view
      • title:输出第一行
      • output:错误信息
        • 您可以使用 .= 追加到它
    2. 对象 $exception
    3. string|null $outputBuffer
    4. CliErrorScreen $screen

render.debug

  • 在调试模式下渲染时发出
  • 参数
    1. array &$view
      • title:输出第一行
      • output:异常信息
        • 您可以使用 .= 追加到它
    2. 对象 $exception
    3. string|null $outputBuffer
    4. CliErrorScreen $screen

事件监听器示例

注意

  • 如果您希望与 PHP 7 中的新异常层次结构兼容,不要在您的监听器中对 Exception 类进行类型提示

记录日志

将未处理的错误记录到文件中。

use Kuria\Error\Util\Debug;

$errorHandler->on('fatal', function ($exception, $debug) {
    $logFilePath = sprintf('./errors_%s.log', $debug ? 'debug' : 'prod');

    $entry = sprintf(
        "[%s] %s - %s in file %s on line %d\n",
        date('Y-m-d H:i:s'),
        Debug::getExceptionName($exception),
        $exception->getMessage(),
        $exception->getFile(),
        $exception->getLine()
    );

    file_put_contents($logFilePath, $entry, FILE_APPEND | LOCK_EX);
});

禁用 "@" 运算符

此监听器会导致类似于 echo @$invalidVariable; 的语句抛出异常,无论是否使用了“安静”运算符。

$errorHandler->on('error', function ($exception, $debug, &$suppressed) {
    $suppressed = false;
});

修改错误屏幕

Web 错误屏幕的示例。

更改非调试错误屏幕的默认标签

use Kuria\Error\Screen\WebErrorScreen;

$errorHandler->on('fatal', function ($exception, $debug, $screen) {
   if (!$debug && $screen instanceof WebErrorScreen) {
        $screen->on('render', function (&$view) {
            $view['heading'] = 'It is all your fault!';
            $view['text'] = 'You have broken everything and now I hate you.';
        });
    }
});

向调试屏幕添加自定义部分

use Kuria\Error\Screen\WebErrorScreen;

$errorHandler->on('fatal', function ($exception, $debug, $screen) {
   if ($debug && $screen instanceof WebErrorScreen) {
        $screen
            ->on('layout.css', function (&$css) {
                $css .= '#custom-group {color: #f60000;}';
            })
            ->on('render.debug', function (&$view) {
                $view['extras'] .= <<<HTML
<div id="custom-group" class="group">
    <div class="section">
        Example of a custom section
    </div>
</div>
HTML;
            })
        ;
    }
});