## 嵌套異常
了解SPL異常之前,我們先了解一下嵌套異常。嵌套異常顧名思義就是異常里面再嵌套異常,一個異常拋出,在catch到以后再拋出異常,這時可以通過`Exception`基類的`getPrevious`方法可以獲得嵌套異常;
```php
<?php
class DBException extends Exception
{
}
class Database
{
/**
* @var PDO object setup during construction
*/
protected $_pdoResource = null;
public function executeQuery($sql)
{
try {
throw new PDOException('PDO error');
} catch (PDOException $e) {
throw new DBException('Query was unexecutable', null, $e);
}
return $numRows;
}
}
try {
$sql = 'select * from user';
$db = new Database('PDO', $connectionParams);
$db->executeQuery($sql);
} catch (DBException $e) {
echo 'General Error: ' . $e->getMessage() . "\n";
// 調用被捕獲異常的getPrevious()獲得嵌套異常
$pdoException = $e->getPrevious();
echo 'PDO Specific error: ' . $pdoException->getMessage() . "\n";
}
```
## SPL異常
簡要的說一下SPL異常的優點:
1. 可以為異常拋出提供分類,方便后續有選擇性的catch異常;
2. 異常語義化更具體,BadFunctionCallException一看就知道是調用錯誤的未定義方法拋出的錯誤;
SPL中有總共13個新的異常類型。其中兩個可被視為基類:邏輯異常(LogicException )和運行時異常(RuntimeException);兩種都繼承php異常類。其余的方法在邏輯上可以被拆分為3組:動態調用組,邏輯組和運行時組。
動態調用組包含異常 BadFunctionCallException和BadMethodCallException,BadMethodCallException是BadFunctionCallException(LogicException的子類)的子類。
```php
// OO variant
class Foo
{
public function __call($method, $args)
{
switch ($method) {
case 'doBar': /* ... */ break;
default:
throw new BadMethodCallException('Method ' . $method . ' is not callable by this object');
}
}
}
// procedural variant
function foo($bar, $baz) {
$func = 'do' . $baz;
if (!is_callable($func)) {
throw new BadFunctionCallException('Function ' . $func . ' is not callable');
}
}
```
邏輯(logic )組包含異常: DomainException、InvalidArgumentException、LengthException、OutOfRangeException組成。
運行時(runtime )組包含異常:
它由OutOfBoundsException、OverflowException、RangeException、UnderflowException、UnexpectedValueExceptio組成。
```php
class Foo
{
protected $number = 0;
protected $bar = null;
public function __construct($options)
{
/** 本方法拋出LogicException異常 **/
}
public function setNumber($number)
{
/** 本方法拋出LogicException異常 **/
}
public function setBar(Bar $bar)
{
/** 本方法拋出LogicException異常 **/
}
public function doSomething($differentNumber)
{
if ($differentNumber != $expectedCondition) {
/** 在這里,拋出LogicException異常 **/
}
/**
* 在這里,本方法拋出RuntimeException異常
*/
}
}
```
## 自定義其它異常
```php
class ThrowableError extends \ErrorException
{
public function __construct(\Throwable $e)
{
// 可以通過instanceof來判斷異常分類(做一個映射)
if ($e instanceof \ParseError) {
$message = 'Parse error: ' . $e->getMessage();
$severity = E_PARSE;
} elseif ($e instanceof \TypeError) {
$message = 'Type error: ' . $e->getMessage();
$severity = E_RECOVERABLE_ERROR;
} else {
$message = 'Fatal error: ' . $e->getMessage();
$severity = E_ERROR;
}
}
}
```
## 鏈接參考
http://cn.php.net/manual/zh/class.exception.php
http://cn.php.net/manual/zh/spl.exceptions.php
http://www.oschina.net/translate/exception-best-practices-in-php-5-3
- 現代化PHP特性
- php7常用特性整理
- 反射機制Reflection
- 依賴注入與服務容器
- 抽象類與接口
- 類多繼承的替代方案Traits
- 類的延遲綁定(后期綁定)
- 生成器語法
- 匿名函數和閉包
- 匿名類
- 理解php的output buffer
- 斷言ASSERT
- 魔術方法小結
- Zend Opcache字節碼緩存
- 內置的http服務器
- SPL標準庫
- 【SPL標準庫專題(1)】SPL簡介
- 【SPL標準庫專題(2)】Iterator
- 【SPL標準庫專題(3)】Classes
- 【SPL標準庫專題(4)】Exceptions
- 【SPL標準庫專題(5)】Datastructures:SplDoublyLinkedList
- 【SPL標準庫專題(6)】Datastructures:SplStack & SplQueue
- 【SPL標準庫專題(7)】Datastructures:SplPriorityQueue
- 【SPL標準庫專題(8)】Datastructures:SplHeap & SplMaxHeap & SplMinHeap
- 【SPL標準庫專題(9)】Datastructures:SplFixedArray
- 【SPL標準庫專題(10)】Datastructures:SplObjectStorage
- PHPcomposer使用手札[ing]
- PHP中的多態
- 通過命名空間實現自動加載的框架雛形
- 日期與金額
- PHPstorm使用攻略
- 筆記本