参考
http://php.net/manual/zh/language.exceptions.php
http://php.net/manual/zh/reserved.exceptions.php (Exception类)
http://www.runoob.com/php/php-exception.html (简单的应用例子)
使用经验
异常被catch再重新throw,会造成异常输出的函数堆栈并不是发生异常的实际位置。
===================================
多层次统一处理返回值。
调用多层函数时,如果顶层函数需要获得最终的执行结果,需要一层一层网上返回。
1 <?php 2 3 function func1() 4 { 5 $ret = func2(); 6 if ($ret == FALSE) { 7 return $ret; 8 } else { 9 //do something 10 } 11 } 12 13 function func2() 14 { 15 return FALSE; 16 } 17 18 echo func1();
如果使用异常机制,只需要在发生错误时throw异常,然后在顶层catch即可。
1 <?php 2 3 function func1() 4 { 5 func2(); 6 } 7 8 function func2() 9 { 10 throw new Exception("get error"); 11 } 12 13 try { 14 func1(); 15 } catch (Exception $e) { 16 echo $e->getMessage(); 17 }
===================================
函数内统一处理返回值。
如:同样都是遇到错误后就返回到上一层,但是func2写法可以统一处理错误,添加处理错误的逻辑。
1 <?php 2 3 function func1() 4 { 5 $a = $b = $c = 1; 6 if ($a) { 7 return FALSE; 8 } 9 10 if ($b) { 11 return FALSE; 12 } 13 14 if ($c) { 15 return FALSE; 16 } 17 } 18 19 function func2() 20 { 21 $a = $b = $c = 1; 22 try { 23 if ($a) { 24 throw new Exception($a); 25 } 26 27 if ($b) { 28 throw new Exception($a); 29 } 30 31 if ($c) { 32 throw new Exception($a); 33 } 34 } catch (Exception $e) { 35 //do something 36 return FALSE; 37 } 38 }
===================================
异常导致for循环提前结束。
如:在执行到$i==5的时候,循环就结束了,而实际上我们的需求是抛出异常后继续执行下一个循环。
1 <?php 2 3 function func($i) 4 { 5 if ($i == 5) 6 throw new Exception($i); 7 } 8 9 try { 10 for ($i = 1; $i <= 10; $i++) { 11 func($i); 12 } 13 } catch (Exception $e) { 14 echo $e->getMessage() . PHP_EOL; 15 }
触发异常的时机
1. 使用throw主动抛出:主动调用 throw抛出异常之后,之后的代码就不会再执行了,直接回跳到catch的地方。
2. 程序执行错误是不会自动抛出异常的:异常和错误是不同的东西!!
如下图:这种情况不是不会抛出异常的。
设置异常默认处理器
如果异常一直都没有被catch到,那么异常最终会由默认异常处理器去处理。
如:
1 <?php 2 set_exception_handler("my_exception"); 3 function my_exception(Exception $e) 4 { 5 echo $e->getMessage(); 6 } 7 8 throw new Exception("I am Exception");
自定义异常类
用于精细化异常,判断异常的类别,然后执行不同的异常处理
如:
1 <?php 2 3 class MySQLException extends Exception 4 { 5 } 6 7 class RedisException extends Exception 8 { 9 } 10 11 try { 12 13 } catch (MySQLException $e) { 14 echo $e->getMessage(); 15 } catch (RedisException $e) { 16 echo $e->getMessage(); 17 }