# 基本语法

PHP 有一个类似于其他编程语言的异常模型。一个异常可以在 PHP 中被抛出和捕获。代码可以被包围在 `try` 块中，以便于捕获潜在的异常。每个 `try` 块中必须至少有一个相应的 `catch` 或 `finally` 块。抛出的对象必须是 `Exception` 类或 `Exception` 类的子类的一个实例。尝试抛出一个非对象将导致 PHP 致命错误。可以使用多个 `catch` 块来捕获不同类别的异常。正常执行（当 `try` 块中没有抛出异常时）将在顺序定义的最后一个 `catch` 块之后继续。可以在 `catch` 块中抛出（或重新抛出）异常。 `try` 中的代码一旦抛出异常，代码将停止运行，直接执行 `catch` 中的代码， PHP 将尝试查找第一个匹配的 `catch` 块。如果未捕获异常，则将发出带有 `Uncaught Exception ...` 消息的 PHP 致命错误，除非已使用 `set_exception_handler()` 函数定义了处理程序。也可以在 `catch` 块之后指定 `finally` 块。 `finally` 块中的代码将始终在 `try` 和 `catch` 块之后执行，无论是否抛出异常，并且在正常执行恢复之前。

```php
<?php

/**
 * Throwing an exception or return a string.
 *
 * @param  bool   $option
 * @return string
 */
function foo(bool $option): string
{
    if ($option) {
        throw new Exception('bar');
    }
    return 'foo';
}

try {
    var_dump(foo(false));
    var_dump(foo(true));
} catch (Exception $e) {
    var_dump($e->getMessage());
}

var_dump('baz');
// string(3) "foo"
// string(3) "bar"
// string(3) "baz"

```

使用 `finally` 块进行异常处理。

```php
<?php

/**
 * Throwing an exception or return a string.
 *
 * @param  bool   $option
 * @return string
 */
function foo(bool $option): string
{
    if ($option) {
        throw new Exception('bar');
    }
    return 'foo';
}

try {
    var_dump(foo(false));
} catch (Exception $e) {
    var_dump($e->getMessage());
} finally {
    var_dump(false);
}

try {
    var_dump(foo(true));
} catch (Exception $e) {
    var_dump($e->getMessage());
} finally {
    var_dump(true);
}

var_dump('baz');
// string(3) "foo"
// bool(false)
// string(3) "bar"
// bool(true)
// string(3) "baz"

```

嵌套异常。

```php
<?php

class Foo
{
    /**
     * Throwing an exception.
     *
     * @param  void
     * @return void
     */
    public function method()
    {
        try {
            try {
                throw new Exception('foo');
            } catch (Exception $e) {
                throw $e;
            }
        } catch (Exception $e) {
            var_dump($e->getMessage());
        }
    }
}

$foo = new Foo();
$foo->method(); // string(3) "foo"

```

