bakame / aide-error
一个用于处理PHP函数错误的简单类
Requires
- php: ^8.1
README
一个用于帮助处理PHP错误报告的 cloak 系统。
注意
aide的错误子模块。
⚠️ 这是一个子模块,对于 pull request 和问题,请访问: https://github.com/bakame-php/aide
安装
Composer
composer require bakame-php/aide-error
系统要求
您需要
- PHP >= 8.1,但推荐使用最新的稳定版PHP
用法
传统上,正确处理PHP函数的错误有两种(2)种方法。要么您使用@
来抑制错误,这是不建议的;要么您需要围绕set_error_handler
和restore_error_handler
添加一些样板代码。
Bakame\Aide\Error\Cloak
实用类通过为您做繁重的工作来帮助您减轻这种负担。
<?php use Bakame\Aide\Error\Cloak; //using the @ suppression operator $res = @touch('/foo'); // bad and not recommended //using error handler set_error_handler(fn (int $errno, string $errstr, string $errfile = null, int $errline = null) { if (!(error_reporting() & $errno)) { // This error code is not included in error_reporting return; } throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); }, E_WARNING); $res = touch('/foo'); restore_error_handler(); // better but having to write this everytime is overkill // and you have little control //using Cloak $touch = Cloak::warning(touch(...)); $res = $touch('/foo'); $touch->errors(); // returns a CloakedErrors instance // the instance is empty on success // otherwise contains all the \ErrorException // generated during the closure execution
您可以通过全局代码库来控制其行为
<?php use Bakame\Aide\Error\Cloak; Cloak::throwOnError(); try { $touch = Cloak::warning(touch(...)); } catch (ErrorException $exception) }
或者您可以选择为特定的调用特别更改其默认行为。
<?php use Bakame\Aide\Error\Cloak; Cloak::throwOnError(); // by default calls via Cloak should throw if (!$touch = Cloak::warning(touch(...), Cloak::SILENT)) { // errors are still available via the `errors` method // but throwing will not happen $touch->errors(); }
可用的属性和方法
访问错误
要访问存储在实例中的错误,您需要调用Cloak::errors
方法,这将返回一个CloakedErrors
实例。此容器允许您访问在回调的最后一次执行期间生成的所有ErrorException
。如果在上一次类执行期间没有发生错误,则CloakedErrors
实例将为空。
$touch = Cloak::all(touch(...)); $touch('/foobar'); $errors = $touch->errors(); // $errors is a CloakedErrors instance $errors->isEmpty(); //true if the execution generated 0 ErrorException; false otherwise foreach ($errors as $error) { $error; //ErrorException instances ordered from the newest to the oldest one. } $errors->first(); // the oldest ErrorException $errors->last(); // the newest ErrorException $errors->get(2); $errors->get(-2); // returns any of the ErrorException and accept negative index. // the three (3) methods will return `null` if no exception // exists for the specified offset
控制是否抛出错误。
该类的一般行为由两个(2)个静态方法控制。在所有情况下,如果发生错误,它将被转换为ErrorException
并通过Cloak::errors
方法使其可访问。区别在于
Cloak::throwOnError
:每个实例都会在第一个错误上抛出;Cloak::silentOnError
:不会抛出任何异常;
注意
为了尊重PHP的行为,Cloak
默认使用Cloak::silentOnError
命名构造函数
为了方便使用,添加了命名构造函数
<?php use Bakame\Aide\Error\Cloak; Cloak::env(); // will use the current environment error reporting value // and one for each error reporting level that exists in PHP Cloak::all(); Cloak::error(); Cloak::warning(); Cloak::notice(); Cloak::deprecated(); Cloak::userError(); Cloak::userWarning(); Cloak::userNotice(); Cloak::userDeprecated(); // some Error reporting will never get triggered // they exist for completeness but won't be usable.
它们都具有相同的签名
static method(Closure $callback, int $onError = Cloak::OBEY);
$onError
参数用于调整实例在错误时的行为
Cloak::THROW
将覆盖一般行为并强制抛出异常(如果可用)Cloak::SILENT
将覆盖一般行为并静默错误(如果存在)Cloak::OBEY
将遵守当前的一般行为。
如果您确实需要其他更精细的错误级别,您仍然可以使用如下所示的构造函数
<?php use Bakame\Aide\Error\Cloak; $touch = new Cloak( touch(...), Cloak::THROW, E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED, );
ReportingLevel类
因为有时处理PHP错误报告级别可能会令人困惑,该包提供了一种更友好的方法来处理它们。例如,前面的代码示例可以使用ReportingLevel
类重写。
<?php use Bakame\Aide\Error\Cloak; use Bakame\Aide\Error\ReportingLevel; $touch = new Cloak( touch(...), Cloak::THROW, ReportingLevel::fromExclusion(E_NOTICE, E_STRICT, E_DEPRECATED), );
该类提供了一个更友好的API来简化对错误报告级别的操作
ReportingLevel::fromValue
允许使用您想要的任何值实例化该类。ReportingLevel::fromName
允许使用与之一致的字符串实例化该类E_*
常量。ReportingLevel::fromEnv
将类实例化为与当前环境设置匹配。ReportingLevel::fromInclusion
通过使用位OR
操作将所有提交的值添加到从0
开始的值中实例化错误级别,这意味着如果没有添加任何错误报告级别,则不存在错误报告级别。ReportingLevel::fromExclusion
执行相反的操作,每个给出的值都会从由E_ALL
表示的最大值中减去。
除此之外,该类还提供了一个用于每个错误报告级别的构造,语法如下
use Bakame\Aide\Error\ReportingLevel; ReportingLevel::warning()->value(); // returns the same value as E_WARNING. ReportingLevel::userDeprecated()->value(); // returns the same value as E_USER_DEPRECATED. // and so on for each error reporting level
您可以使用contains
方法来判断正在配置哪种错误报告。该类还提供了excluded
和included
方法,这两个方法返回错误报告级别的名称。
<?php use Bakame\Aide\Error\ReportingLevel; ReportingLevel::fromEnv()->contains(E_WARNING); // returns true if the current value in error_reporting contains `E_WARNING` // returns false otherwise. $reportingLevel = ReportingLevel::fromInclusion(E_NOTICE, "E_DEPRECATED"); $reportingLevel->value(); // `value` returns the int value corresponding to the calculated error level. // the errorLevel calculated will ignore notice, and deprecated error. $reportingLevel->excluded(); // returns all the error reporting level name no present in the current error Level $reportingLevel->included(); // returns all the error reporting level name present in the current error Level // ["E_NOTICE", "E_DEPRECATED"]
从Cloak实例访问错误报告级别
一旦实例化,您就可以始终通过Cloak实例上的errorLevel
方法来访问错误报告级别。例如,如果您需要知道是否包含特定错误,可以执行以下操作
$touch = Cloak::all(touch(...)); $touch->reportingLevel()->contains(E_WARNING); //tells if the E_WARNING is included or not