异常处理的场景
- 避免在项目中充斥if…else,提高代码的可读性。
- 异常处理可以强迫开发人员消除问题,或者把问题交给能解决它的环境。
- 把“描述在正常过程中做什么事的代码“跟”出了问题怎么办的代码“进行隔离
PHP异常处理的特点
- 【注】很多时候不是直接写上try…catch就万事大吉了。
- PHP一旦遇到非正常代码通常都会出发错误,而不是异常。这个意义上,如果想使用异常处理不可预料的问题是办不到的,如文件不存在、数据库连接不上,这在PHP里把它作为错误抛出,而不是作为异常自动捕获。
- PHP一般需要主动throw后才能捕获异常。
- 不同于java,PHP通常无法捕获有意义的异常,它把所有不正常的情况都是为错误。若有捕获这个异常,就得使用if…else结构,保证代码是正常的,然后判断如除数为0,手动抛出再捕获。
- Exception类作为超类应该放在最后捕获,不然捕获这个异常后,后面的捕获就停止了。
- 从业务这个角度讲,异常偏重于保护数据一致性,并且强调对异常业务的处理
以上两点总结主要摘自《PHP核心技术与最佳实践》
Throwable
Throwable 是 PHP 7 中可以用作任何对象抛出声明的基本接口,包括 Expection (异常)和 Error (错误)。
异常处理示例(Lavarel)
<?php
namespace App\Http\Controllers\v1\Demo;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Exception;
use App\Lib\Common;
class ExceptionDemoController extends Controller
{
function demo(Request $request){
//捕获自定义抛出的异常
try{
$val='something not you need';
//异常发生
$accept_val=$this->acceptVal($val);
return Common::response([
'val'=>$val,
'accept_val'=>$accept_val,
]);
}catch(Exception $e){
return Common::response($e->getCode(),$e->getMessage());
}
return Common::response();
}
function curlExceptionDemo(){
//设置不存在的url让curl发生异常
$url='http://www.unkowndomain.net/unknown-path/';
try{
$data_arr['curl']=Common::http($url);
}
catch(Exception $e){
return Common::response($e->getCode(),$e->getMessage());
}
return Common::response($data_arr);
}
function fileExceptionDemo(){
//设置不存在的url(资源路径)让fopen执行发生异常,数据库连接异常可以参考使用,
// 关键是使用错误控制运算符@符号,避免直接暴露异常(错误)
$url='http://www.unkowndomain.net/unknown-path/';
try{
$fo=@fopen($url);
if(!$fo){
//手动抛出
throw new Exception('resource not found', 555);
}
$data_arr['fopen']=$fo;
}
catch(Exception $e){
return Common::response($e->getCode(),$e->getMessage());
}
return Common::response($data_arr);
}
function acceptVal($val){
// 手动抛出
if($val!='what_i_need'){
throw new Exception('it is not what i need', 550);
}
return 'anything i need';
}
}