PHP7异常和错误处理机制Exception, Error, Throwable
Exception, Error, ThrowablePHP Exception, Error, Throwable
- PHP 来自中将代码本身的异常(通常是由环境或语法引起的**)是错误称为
Error,运行过程中出现的逻辑错误称为Exception - 错误,无法通过代码处理,而异常可以通过
try /catch 处理 - PHP7 * *
Throwable 接口现已推出。该接口由Error和Exception实现。用户无法直接实现 Throwable 接口,只能通过继承 Exception来实现该接口
PHP7 异常处理机制
Error,运行过程中出现的逻辑错误称为Exceptiontry /catch 处理Throwable 接口现已推出。该接口由Error和Exception实现。用户无法直接实现 Throwable 接口,只能通过继承 Exception来实现该接口 以前都是处理 fatal PHP 中几乎不可能出现错误。致命错误不会调用 set_error_handler() 设置的处理程序,而只是停止脚本运行。
在 PHP7 中,当发生致命错误和可捕获错误(E_ERROR 和 E_RECOVERABLE_ERROR)时,会抛出异常,而不是立即停止脚本。在某些情况下,例如内存溢出,致命错误仍然会立即停止脚本执行,就像以前一样。在 PHP7 中,未捕获的异常也是致命错误。这意味着在 PHP5.x 中作为致命错误抛出的异常不会被捕获,并且在 PHP7 中也是致命错误。
注意:其他级别的错误如警告和通知不会像以前那样抛出异常,只有致命和恢复条 水平错误会破例的。
由致命和可恢复级别错误引发的异常不会从Exception类继承。这种分离是为了防止现有的 PHP5.x 代码用于防止脚本也捕获错误抛出的异常。由 fatal 和 recoverable 级别错误引起的异常是新分离的类 Error 的实例。与其他异常一样,Error类异常也可以被捕获和处理,并且也可以在块结构中运行,例如finally。
Throwable
为了统一两个异常分支,Exception和Error都实现了一个新接口:Throwable
PH P7中新的异常结构如下:
interface Throwable
|- Exception implements Throwable
|- ...
|- Error implements Throwable
|- TypeError extends Error
|- ParseError extends Error
|- ArithmeticError extends Error
|- DivisionByZeroError extends ArithmeticError
|- AssertionError extends Error
如果类Throwable是在PHP7代码中定义的,它将如下所示:
interface Throwable
{
public function getMessage(): string;
public function getCode(): int;
public function getFile(): string;
public function getLine(): int;
public function getTrace(): array;
public function getTraceAsString(): string;
public function getPrevious(): Throwable;
public function __toString(): string;
}
这个界面看起来很熟悉。 Throwable指定的方法与Exception几乎相同。唯一的区别是 Throwable::getPrevious() 返回 Throwable 的实例,而不是 Exception。 Exception和Error的构造函数与之前的Exception相同,可以接受任何Throwable的副本。
Throwable 可在 try/catch 块中使用,以删除 Exception 和 Error- 对象(或是未来可能的异常类型) 。请记住,最好识别更具体的异常类型并进行相应的处理。然而,在某些情况下我们想要捕获任何类型的异常(例如框架中的日志记录或错误处理)。 要捕获所有内容,在 PHP7 中,您应该使用 Throwable 而不是 Exception。
try {
// Code that may throw an Exception or Error.
} catch (Throwable $t) {
// Handle exception
}
用户定义的类无法实现Throwable接口。做出此决定的部分原因是为了可预测性和一致性:只能抛出 Exception 和 Error 对象。此外,异常必须包含有关在回溯堆栈中创建对象的位置的信息,并且用户定义的对象不会自动具有用于存储此信息的参数。可以采用
Throwable来创建特定于包的接口或添加其他方法。从 Throwable 继承的接口只能通过子类化 Exception 或 Error 来实现。事实上,PHP5.X 中的所有错误都是Fatal 或Recoverable 中的错误。 示例。与任何其他异常一样,可以使用 try/catch 块捕获Error 对象。
$var = 1;
try {
$var->method(); // Throws an Error object in PHP 7.
} catch (Error $e) {
// Handle error
}
通常,以前的致命错误会抛出基类实例Error,但有些错误会抛出更具体的Error子类:TypeError, ParseError 和 AssertionError。
TypeError
当函数参数或返回值与声明的类型不匹配时,会抛出 TypeError 的实例。
function add(int $left, int $right)
{
return $left + $right;
}
try {
$value = add('left', 'right');
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
//Argument 1 passed to add() must be of the type integer, string given
ParseError
如果文件中存在语法错误include/require或eval()代码,ParseError 被抛出。
try {
require 'file-with-parse-error.php';
} catch (ParseError $e) {
echo $e->getMessage(), "\n";
}
算术错误
算术错误在两种情况下产生。其中之一是搬迁操作的负面影响。第二个是在分子为PHP_INT_MIN时调用Intdiv()(),分母为-1(使用dission operator的此表达式:PHP_INT_MIN /-1,结果是浮点类型)。
try {
$value = 1 << -1;
catch (ArithmeticError $e) {
echo $e->getMessage();//Bit shift by negative number
}
Zererror除法
当intdiv()的分母为或模运算(%)中的分母为0时,除法为Zererror抛出。请注意,在除法运算符 (/) 中使用 0 作为除数(即写为 xxx/0)只会触发警告。如果此时计数器不为零,则结果为 INF,如果计数器为 0,则结果为 NaN。
try {
$value = 1 % 0;
} catch (DivisionByZeroError $e) {
echo $e->getMessage();//Modulo by zero
}
AssertionError
如果不满足assert()的条件,则会抛出AssertionError。
ini_set('zend.assertions', 1);
ini_set('assert.exception', 1);
$test = 1;
assert($test === 0);
//Fatal error: Uncaught AssertionError: assert($test === 0)
仅启用断言并设置 ini 配置 用户可以利用 zend.assertions = 1 和 assert.exception = 1 、 assert() 被执行并且抛出 ,然后断言错误。 使用Error
Error创建符合自己级别要求的Error类。这就提出了一个问题:什么情况下应该滚动Exception,什么情况下应该滚动Error。 错误应用于指示需要程序员注意的代码问题。 PHP 引擎抛出的Error 对象属于这些类别,通常是代码级错误,例如将错误类型的参数传递给函数或解析文件时发生错误。当可以在运行时安全处理并且可以执行某些其他操作时,应使用Exception。由于 Error 对象不应在运行时处理,因此捕获 Error 对象也应该很少发生。一般来说,记录Error对象仅用于记录目的、执行必要的清理以及向用户显示错误消息。 编写代码以支持 PHP5 中的异常。
异常。什么时候支持PHP5。
try {
// Code that may throw an Exception or Error.
} catch (Throwable $t) {
// Executed only in PHP 7, will not match in PHP 5.x
} catch (Exception $e) {
// Executed only in PHP 5.x, will not be reached in PHP 7
}
不幸的是,处理异常的函数中的类型声明不容易确定。当 Exception 用于函数参数类型声明并且调用函数时可以使用 Error 的实例时,该类型声明将被删除。如果不需要支持 PHP5.x,可以将类型声明重置为Throwable。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网
