# 异常处理（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();
```
