mensbeam / catcher
Requires
- php: >=8.1
- mensbeam/self-sealing-callable: ^1.0
- psr/log: ^3.0
Requires (Dev)
- mikey179/vfsstream: ^1.6
- phake/phake: ^4.4
- phpunit/phpunit: ^10
README
Catcher 是一个用于 PHP 的 Throwable 捕获和错误处理的库。错误处理通过基于堆栈的方法完成。
Catcher 使用名为 handler 的类来处理发送给它的可抛出对象。PHP 在错误处理方面目前处于动荡状态。有传统的 PHP 错误,通过使用 trigger_error()
在用户空间触发,无法使用 try
/catch
捕获,并且通常很难处理。PHP 通过引入 \Error
类及其各种子类开始解决这个问题。然而,许多函数和语言本身的核心方面仍然继续使用遗留错误。此类尝试通过将致命错误抛出为 \Error
来使这一点更容易。可以动态配置 Catcher 以抛出非致命错误,让您可以像捕获异常一样轻松地捕获它们。
要求
- PHP >= 8.1
- mensbeam/self-sealing-callable ^1.0
- psr/log ^3.0
安装
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。默认为true。prettyPrintWhenLogging:如果为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]"。