PHP7异常和错误处理机制Exception, Error, Throwable
Exception, Error, ThrowablePHP Exception, Error, Throwable
- PHP 来自中将代码本身的异常(通常是由环境或语法引起的**)是错误称为
Error
,运行过程中出现的逻辑错误称为Exception
- 错误,无法通过代码处理,而异常可以通过
try /catch 处理
- PHP7 * *
Throwable
接口现已推出。该接口由Error
和Exception
实现。用户无法直接实现 Throwable 接口,只能通过继承 Exception
来实现该接口
PHP7 异常处理机制
Error
,运行过程中出现的逻辑错误称为Exception
try /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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。