# 异常处理（Exceptions）

* 文件找不到！
* 数据库连接失败！
* URL接口访问失败！
* 磁盘空间不足！
* 等等

怎么办?

**避免使用:**

* die()
* return false

**解决办法:**

使用异常处理

```php
  try {
      //好好干，出了问题就抛出去
  } catch (Exception $e) {
      //时刻准备着，接 Exception ！
  } finally {
      //怎么玩都逃不出我的手掌心
  }
```

注意：try 中 return 后 finally 会继续执行，如果 finally 中也有return，则最终返回值为 finally 中 return 的值。

try 中 die 或 exit 后 finally 不会执行。

php7 下实例:

```php
if(php_sapi_name() != 'cli') ob_start('nl2br');

function trytest() {
    try {
        echo "try\n";
        //throw new Exception("I'm dying, Help!!");
        //die;
        return false;
    } catch ( Exception $e ) {
        echo $e->getMessage()."\n";
    } finally {
        echo "finally\n";
        return true;
    }
}

var_dump(trytest());
```

结果:

```
try
finally


boolean true
```

## 设置自己的错误处理函数

PHP 中充满了 Notice、Warning等,可以采用设置自己的错误处理函数来捕捉.

如下面的错误:

```
Warning: file_get_contents() expects at least 1 parameter, 0 given in xxxxx
```

**可以设置自己的错误处理函数:**

```
set_error_handler (callable $handler [, int $error_types ]);
```

默认的PHP错误处理流程会绕过 $error\_types 中指定的错误类型，除非 $handler 中返回false(当返回false 则不会绕过,无法拦截,并且报错)；

如果myErrorHandler正常拦截, error\_reporting() 不再有效，除非自己在 $handler 中按当前的 error\_reporting 作出判断；

```php
// 可通过 set_error_handler + ErrorException 拦截php默认报错，转为异常
function trytest() {
    try {
        file_get_contents(); // parameter missing. w
    } catch (Exception $e) {
        echo $e->getMessage()."\n";
    } finally {
        return true;
    }
}

function myErrorHandler($errno, $errstr, $errfile, $errline){
    throw new ErrorException("Exception: ".$errstr, 0, $errno, $errfile, $errline);
}

set_error_handler("myErrorHandler");

trytest();
```

但是，set\_error\_handler 只能拦截部分错误，对于如下拦截不了的怎么办？

E\_ERROR, E\_PARSE, E\_CORE\_ERROR, E\_CORE\_WARNING, E\_COMPILE\_ERROR, E\_COMPILE\_WARNING, 调用该函数的文件中出现的 E\_STRICT

思路: 通过`register_shutdown_function`函数注册一个在代码执行完毕后自动调用的函数

```php
//error_reporting(0);

register_shutdown_function(function() {
    if ($error = error_get_last()) {
        print_r($error);
    }
});

// Fatal error: Call to undefined function test()
test();
```


---

# 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://phper.shujuwajue.com/php-gao-ji-te-xing/yi-chang-chu-li-ff08-exceptions.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.
