mensbeam/catcher

捕获异常、错误和关闭

v2.1.5 2024-02-20 21:15 UTC

This package is auto-updated.

Last update: 2024-09-20 22:28:50 UTC


README

Catcher 是一个用于 PHP 的 Throwable 捕获和错误处理的库。错误处理通过基于堆栈的方法完成。

Catcher 使用名为 handler 的类来处理发送给它的可抛出对象。PHP 在错误处理方面目前处于动荡状态。有传统的 PHP 错误,通过使用 trigger_error() 在用户空间触发,无法使用 try/catch 捕获,并且通常很难处理。PHP 通过引入 \Error 类及其各种子类开始解决这个问题。然而,许多函数和语言本身的核心方面仍然继续使用遗留错误。此类尝试通过将致命错误抛出为 \Error 来使这一点更容易。可以动态配置 Catcher 以抛出非致命错误,让您可以像捕获异常一样轻松地捕获它们。

要求

安装

composer require mensbeam/catcher

用法

对于大多数用例,此库不需要配置,并且可以轻松集成到非复杂环境中。

use MensBeam\Catcher;

$catcher = new Catcher();

就是这样。它将自动将 Catcher 注册为异常、错误和关闭处理程序,并使用 PlainTextHandler 作为其唯一处理程序。 Catcher 完全可配置,可以配置为使用一个或多个 handler。目前只有一个处理程序,即上述的 PlainTextHandler。所有处理程序都可以配置为记录错误,如下所示

use MensBeam\Catcher,
    MensBeam\Logger;

$catcher = new Catcher(
    new PlainTextHandler([
        'logger' => new Logger('log'),
        'silent' => true
    ])
);

上述示例使用 Logger 作为其日志记录器,但任何 PSR-3 兼容的日志记录器都可以工作。

有关提示、警告等的说明

如本文件开头摘要段落中所述,Catcher 默认将所有致命错误转换为 Throwable,并将警告、提示等保留原样。但是,它可以配置为抛出这些错误。

$catcher = new Catcher();
$catcher->errorHandlingMethod = Catcher::THROW_ALL_ERRORS;

try {
    trigger_error(\E_USER_WARNING, 'Ook!');
} catch (\Throwable $t) {
    echo $t->message();
}

输出

Ook!

错误处理

PHP 默认不允许错误处理程序处理致命错误。它将打印错误并退出。但是,在代码执行停止之前,将运行任何关闭函数。Catcher 将检索最后一个错误并手动处理它。这导致多个相同的错误实例被输出。因此,Catcher 通过在注册处理程序时始终从其中删除 E_ERROR 来更改错误报告级别。在注销时,将 E_ERROR 逻辑或回错误报告级别。如果此行为不受欢迎,则可以在 Catcher 实例化后任何时间手动将 E_ERROR 包括回错误报告级别。请注意,如果错误报告级别在 Catcher 实例化后被修改,或者错误报告级别在 Catcher 注册其处理程序时没有它,则 Catcher 不会E_ERROR 包括回错误报告级别掩码。

文档

MensBeam\Catcher

这是库中的主要类。除非您需要配置处理程序或使用多个处理程序,否则通常不需要与库的其他部分进行交互。

namespace MensBeam;
use MensBeam\Catcher\Handler;

class Catcher {
    public const THROW_NO_ERRORS = 0;
    public const THROW_FATAL_ERRORS = 1;
    public const THROW_ALL_ERRORS = 2;

    public int $errorHandlingMethod = self::THROW_FATAL_ERRORS;
    public bool $preventExit = false;

    public function __construct(Handler ...$handlers);

    public function getHandlers(): array;
    public function getLastThrowable(): ?\Throwable;
    public function isRegistered(): bool;
    public function popHandler(): Handler;
    public function pushHandler(Handler ...$handlers): void;
    public function register(): bool;
    public function setHandlers(Handler ...$handlers): void;
    public function shiftHandler(): Handler;
    public function unregister(): bool;
    public function unshiftHandler(Handler ...$handlers): void;
}

常量

THROW_NO_ERRORS:当在 errorHandlingMethod 中使用时,将导致 Catcher 不抛出任何错误。
THROW_FATAL_ERRORS:当在 errorHandlingMethod 中使用时,将导致 Catcher 仅抛出致命错误;这是默认行为。
THROW_ALL_ERRORS:当在 errorHandlingMethod 中使用时,将导致 Catcher 抛出所有错误。
NOW:当在输出掩码中返回时,将导致 Catcher 立即调用处理程序。
输出:当在输出位掩码中返回时,它会导致在调用时处理程序输出可抛出对象。

属性

errorHandlingMethod:确定如何处理错误;存在THROW_*常量以控制
preventExit:当设置为true时,即使在发生致命错误或异常后,Catcher也不会退出

MensBeam\Catcher::getHandlers

返回一个数组,其中包含为Catcher实例定义的处理程序

MensBeam\Catcher::getLastThrowable

返回Catcher此实例所处理的上一个可抛出对象

MensBeam\Catcher::isRegistered

返回Catcher是否仍作为错误、异常和关闭处理程序注册

MensBeam\Catcher::popHandler

从堆栈中弹出最后一个处理程序并返回它

MensBeam\Catcher::pushHandler

将指定的处理程序推送到堆栈上

MensBeam\Catcher::register

将Catcher实例注册为错误、异常和关闭处理程序。默认情况下,构造函数会自动执行此操作,但此方法存在以便在调用unregister时使用。

MensBeam\Catcher::setHandlers

用指定的参数替换处理程序堆栈

MensBeam\Catcher::shiftHandler

将第一个处理程序从处理程序堆栈中移除并返回它。

MensBeam\Catcher::unregister

取消注册Catcher实例作为错误、异常和关闭处理程序

MensBeam\Catcher::unshiftHandler

将指定的处理程序推送到堆栈的开头

MensBeam\Catcher\Handler

所有处理程序都从该抽象类继承。由于它是一个用于构建处理程序的抽象类,因此受保护的方法和属性也将在此处进行文档说明。

namespace MensBeam\Catcher;

abstract class Handler {
    public const CONTENT_TYPE = null;

    public const NON_FATAL_ERROR = \E_NOTICE | \E_USER_NOTICE | \E_STRICT | \E_WARNING | \E_COMPILE_WARNING | \E_USER_WARNING | \E_DEPRECATED | \E_USER_DEPRECATED;

    // Control constants
    public const BUBBLES = 1;
    public const EXIT = 2;
    public const LOG = 4;
    public const NOW = 8;
    public const OUTPUT = 16;

    protected ?array $lastOutputThrowable;
    protected array $outputBuffer;

    // Options
    protected int $_backtraceArgFrameLimit = 5;
    protected bool $_bubbles = true;
    protected string $_charset = 'UTF-8';
    protected bool $_forceExit = false;
    protected bool $_forceOutputNow = false;
    protected int $_httpCode = 500;
    protected ?array $_ignore = null;
    protected ?LoggerInterface $_logger = null;
    protected bool $_logWhenSilent = true;
    protected bool $_outputBacktrace = false;
    protected bool $_outputPrevious = true;
    protected bool $_outputTime = true;
    protected bool $_outputToStderr = true;
    protected bool $_silent = false;
    protected string $_timeFormat = 'Y-m-d\TH:i:s.vO';

    public function __construct(array $options = []);

    public function __invoke(): void;
    public function getLastOutputThrowable(): ?array;
    public function getOption(string $name): mixed;
    public function setOption(string $name, mixed $value): void;

    protected function buildOutputArray(ThrowableController $controller): array;
    protected function cleanOutputThrowable(array $outputThrowable): array;
    abstract protected function handleCallback(array $output): array;
    abstract protected function invokeCallback(): void;
    protected function log(\Throwable $throwable, string $message): void;
    protected function print(string $string): void;
    protected function serializeArgs(mixed $value): string;
}

常量

CONTENT_TYPE:处理程序输出的内容的MIME类型

BUBBLES:当在输出位掩码中返回时,它会导致在处理之后继续堆栈循环到下一个处理程序;这是默认行为。
EXIT:当在输出位掩码中返回时,它会导致Catcher在运行所有处理程序后退出。
LOG:当在输出位掩码中返回时,它会导致Catcher将输出记录到提供的记录器。
NOW:当在输出掩码中返回时,将导致 Catcher 立即调用处理程序。
输出:当在输出位掩码中返回时,它会导致在调用时处理程序输出可抛出对象。

属性(受保护)

outputBuffer:这是存储代表已处理可抛出对象的输出数组的存储位置,直到它们被分派。

选项

所有以下划线开头的属性都是选项。它们可以通过构造函数设置,也可以通过setHandler以名称设置,删除开头的下划线。所有处理程序都继承这些选项。继承类中的选项也应以下划线开头(_)。如何在文档的进一步部分中扩展Handler将进行说明。

backtraceArgFrameLimit:可以输出带有它们的帧的数量。默认为5
bubbles:如果为true,则处理程序将转到处理程序堆栈中的下一个项目。默认为true
charset:输出的字符集;仅在错误发生之前未发送标题时使用。不执行转换。默认为"UTF_8"
forceBreak:当设置时,这将强制在处理程序运行后中断堆栈循环。默认为false
forceExit:当设置时,这将强制在所有处理程序运行后退出。默认为false
forceOutputNow:当设置时,这将立即强制输出处理程序。默认为false
httpCode:要发送的HTTP代码;可能的值是200、400-599。默认为500
ignore:要忽略的类字符串或错误代码位掩码数组。默认为null(不忽略)。
logger:要记录到的PSR-3兼容的记录器。默认为null(不记录)。
logWhenSilent:当设置为true时,处理程序即使在静默模式下也会发送日志。默认为true
outputBacktrace:当为true时将输出堆栈跟踪。默认为false
outputPrevious:当为true时将输出之前的可抛出对象。默认为true
outputTime:当为true时将输出时间到输出。默认为true
outputToStderr:当SAPI是命令行时,将错误输出到stderr。默认为true
silent:当为true时,处理器不会输出任何内容。默认为false
timeFormat:PHP标准日期格式,用于输出中的时间。默认为"Y-m-d\TH:i:s.vO"

MensBeam\Catcher\Handler::__invoke

输出存储在输出缓冲区中的可抛出数组。

MensBeam\Catcher\Handler::getLastOutputThrowable

返回由该处理器处理的最后一个输出可抛出数组(如果没有,则返回null);在调试时很有用。

MensBeam\Catcher\Handler::getOption

返回提供的选项名称的值。

MensBeam\Catcher\Handler::handle

处理提供的ThrowableController,并将输出数组存储在输出缓冲区中以便稍后分发。

MensBeam\Catcher\Handler::setOption

使用提供的值设置提供的选项。

MensBeam\Catcher\Handler::buildOutputArray (受保护)

给定ThrowableController将输出一个数组以存储在输出缓冲区中。

MensBeam\Catcher\Handler::cleanOutputThrowable (受保护)

"清理"一个输出可抛出项(输出数组中的单个项)——通过删除输出中不必要的详细信息;对于结构化数据输出(如JSON)很有用。

MensBeam\Catcher\Handler::handleCallback (受保护)

一个回调方法,意味着可以通过继承类扩展,在将输出数组存储在输出缓冲区之前对其进行操作。

MensBeam\Catcher\Handler::invokeCallback (受保护)

一个回调方法,意味着可以通过继承类扩展以控制类如何输出可抛出数组。

MensBeam\Catcher\Handler::print (受保护)

根据处理器配置和使用的SAPI将提供的字符串打印到stderr或stdout。

MensBeam\Catcher\Handler::serializeArgs (受保护)

序列化堆栈跟踪中的参数数组;不递归,仅显示顶级参数。

MensBeam\Catcher\ThrowableController

我们无法要求所有可抛出对象都转换为我们的类,因此此类作为控制器存在,以便为Catcher的可抛出对象添加新功能。

namespace MensBeam\Catcher;

class ThrowableController {
    public function __construct(\Throwable $throwable);

    public function getErrorType(): ?string;
    public function getFrames(int $argFrameLimit = \PHP_INT_MAX): array;
    public function getPrevious(): ?ThrowableController;
    public function getThrowable(): \Throwable;
}

MensBeam\Catcher\ThrowableController::getErrorType

返回MensBeam\Catcher\Error的错误类型,即错误代码的人类友好表示(例如:"致命错误""警告""通知")或如果可抛出对象不是Error,则返回null。

MensBeam\Catcher\ThrowableController::getFrames

返回可抛出的帧作为数组,其中包含去重和修复。

MensBeam\Catcher\ThrowableController::getPrevious

如果有,则返回上一个ThrowableController

MensBeam\Catcher\ThrowableController::getThrowable

返回由该类实例控制的可抛出对象。

MensBeam\Catcher\JSONHandler

namespace MensBeam\Catcher;

class JSONHandler extends Handler {
    public const CONTENT_TYPE = 'application/json';

    protected bool $_prettyPrint = true;
    protected bool $_prettyPrintWhenLogging = false;
}

选项

prettyPrint:如果为true,则处理器将格式化输出JSON。默认为trueprettyPrintWhenLogging:如果为true,则处理器将在记录时格式化输出JSON。默认为false

MensBeam\Catcher\PlainTextHandler

namespace MensBeam\Catcher;

class PlainTextHandler extends Handler {
    public const CONTENT_TYPE = 'text/plain';

    protected string $_timeFormat = '[H:i:s]';
}

选项

timeFormat:与Handler中相同,但默认值更改为"[H:i:s]"