# Throwable 接口

## 目录：

* 简介
* Throwable 层次结构
* Error 对象

## 简介：

PHP7提供了一种全局的接口，使得所有的类都可以基于此使用throw关键字。在PHP中，异常与错误经常会遇到。**在PHP之前，异常可以被捕获，但是错误是不能被捕获的。从PHP7开始，任何完整程序或一部分程序中的Fatal错误都可以被捕获。**

> 为了更好的捕获诸多错误（大多数的 Fatal 错误），PHP7 提供了 throwable 接口，异常与错误都继承于这个接口。
>
> 注意：wom自己写的PHP类是不能直接继承throwable 接口的，如果希望继承throwable 接口，需要继承某个异常类。

PHP 7 改变了大多数错误的报告方式。不同于传统（PHP 5）的错误报告机制，现在大多数错误被作为 **Error** 异常抛出。

## Throwable层次结构：

* Throwable
  * Error
    * ArithmeticError
    * DivisionByZeroError
    * AssertionError
    * ParseError
    * TypeError
  * Exception
    * ...

## Error 对象：

现在大多数的Fatal错误情况会抛出一个Error实例，类似于异常捕获，Error实例可以被try/catch捕获，如下代码：

```php
<?php
function iHaveError($object)
{
    return $object->iDontExist();
}

iHaveError(null);

echo "I am still running";
```

以上代码会产生一个Fatal 的错误，程序也停止运行，并且最后一行的echo语句不会被执行。

现在加入try/catch 后，代码如下：

```php
<?php
function iHaveError($object)
{
    return $object->iDontExist();
}

try {
    iHaveError(null);
} catch(Error $e) {
    echo $e->getMessage();
}

echo "<br>I am still running";
```

再次执行以上代码，catch中的内容将会执行。并且代码会继续执行，最后的一行echo也会被输出。结果如下:

```
Call to a member function iDontExist() on null
I am still running
```

## DivisionByZeroError 对象(Error的子实例)

大多数情况下，Error实例会在大部分 Fatal 错误的情况下被抛出，但是对于一些错误情况，只有Error的子实例（见Error层次图）会被抛出,当然使用 Error 对象也是可以的。

如下代码：

```php
<?php
try {
    $a = 20;
    $division = $a % 0;
} catch(DivisionByZeroError $e) { // catch(Error $e) {
    echo $e->getMessage();
}
```

在PHP7之前，上面的代码会触发一个warning级别的错误，如今在PHP7中，执行上面的代码会抛出一个可以被捕获的DivisionByZeroError异常.如下:

```
Modulo by zero
```

补充:**除以零的变化**

```php
<?php
var_dump(3/0);
var_dump(0/0);
var_dump(0%0);
?>
```

Output of the above example in PHP 5:

```
Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)
```

Output of the above example in PHP 7:

```
Warning: Division by zero in %s on line %d
float(INF)

Warning: Division by zero in %s on line %d
float(NAN)

PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in %s line %d
```

## ParseError 对象(Error的子实例)

> [eval函数](http://php.net/manual/zh/function.eval.php) — 把字符串作为PHP代码执行

当使用eval函数进行对字符串进行解析时,发生 Fatal 错误,如下

```
Parse error: syntax error, unexpected end of file in ....
```

如今在PHP7中，执行下面的代码会抛出一个可以被捕获的ParseError异常.如下:

```php
<?php
try {
    $command = 20;
    $b = eval($command);
} catch (ParseError $e) {
    echo $e->getMessage();
}
```

捕获到的异常如下:

```
syntax error, unexpected end of file
```

## 资料：

[PHP 7 错误处理](http://php.net/manual/zh/language.errors.php7.php)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://php7.shujuwajue.com/php-70x-xin-te-xing/oop-te-xing/throwable-jie-kou.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
