Thinkphp5进阶——01 异常

本文介绍了ThinkPHP5中的异常处理,包括用户行为导致的异常和服务器自身异常的分类,强调了在API开发中正确处理异常的重要性。通过try-catch机制,结合自定义的ExceptionHandler和BaseException类,实现更健壮的错误处理。文章还详细阐述了构建Validate层的步骤,指导如何创建和使用具体异常处理类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

和PHP默认的异常处理不同,ThinkPHP抛出的不是单纯的错误信息,而是一个错误页面。

如果是做web开发,给客户端返回这种错误页面还好;但如果是做API开发的话,返回这个页面客户端根本无法处理,所以我们需要对异常进行捕获处理。




异常分类


用户行为导致的异常

没有通过验证器、没有查询到结果。

通常不需要记录日志,需要向用户返回具体信息。



服务器自身的异常

代码错误、调用外部接口错误。

通常需要记录日志,不需要向客户端返回具体原因。



try-catch

相信对于大部分人而言,try-catch并不陌生。

使用try-catch我们可以在可能发生异常的地方进行异常捕获,然后对异常进行后续处理,返回给客户端可以处理的错误信息。


实例

try{
	// 可能发生异常的业务逻辑
}
catch(Exception $ex){

	// RESTful风格的错误返回信息
	$err = [
	  'error_code'=>10001,
	  'msg'=>$ex->getMessage()
	];
	
	// 返回json格式的错误信息,并且规定HTTP状态码
	return json($err,400);
} 


try-catch这种异常捕获方式存在以下问题:

  1. 逐层抛出,如果是最底下的业务逻辑出现了问题会将异常逐层抛出,否则就会直接被原有的默认异常捕获到输出一个默认的错误页面;

  2. 如果是不可预知的异常,未做try-catch处理的业务逻辑,就会输出一个默认的错误页面;

  3. 某些错误信息不适合直接返回给客户端,需要做统一处理。

总结起来就是繁琐,不够健壮。




构建Validate层

实现步骤大致为:

  1. 自定义错误处理器——ExceptionHandler。

  2. config.php的exception_hadle配置项修改为上面的自定义错误处理器。

  3. 创建基础异常处理类——BaseException。

  4. 创建具体异常处理类——xxxException。



错误处理器——ExceptionHandler

1)模块同级目录下,创建lib/exception文件夹

2)创建ExceptionHandler,继承think\exception\Handle

3)引用Exception类

4)重写render方法
我们定义,凡是继承了BaseException的异常,就属于用户导致的异常。


namespace app\lib\exception;

// 引用框架的Exception
use Exception;

// 引用Log类
use think\facade\Log;

// 引用Request类
use think\facade\Request;

// 引用框架的Handle
use think\exception\Handle;


class ExceptionHandler extends Handle
{
	private $code;
	private $msg;
	private $errorCode;

	// 重写框架的render方法
	public function render(Exception $e){
        
		// 如果是用户类错误
		if($e instanceof BaseException){
		  $this->code = $e->code;
		  $this->msg = $e->msg;
		  $this->errorCode = $e->errorCode;
		}
		// 如果是服务器内部错误
		else{
		  
		  $switch = config('app.app_debug');

		  // 开发模式下显示html页面
		  if($switch){
		    return parent::render($e);
		  }
		  // 生产模式下显示json数据
		  else{
		    $this->code = 500;
		    $this->msg = '服务器内部错误,不想告诉你';
		    $this->errorCode = 999;
    
		    // 写入日志
		    $this->recordErrorLog($e);
		  }
		}

		// 返回数组
		$result = [
		  'msg' => $this->msg,
		  'errorCode' => $this->errorCode,
		  'request_url' => Request::url()
		];

		return json($result,$this->code);
	}


	// 服务器内部错误信息写入日志
	private function recordErrorLog(Exception $e){
		Log::write($e->getMessage(),'error');
	}

}



基础异常处理类——BaseException

1)引用Exception类。

2)定义通用异常错误的属性(http状态码、错误信息、自定义错误码)。

3)构造函数可以传值,覆盖默认属性。


namespace app\lib\exception;

use Exception;

class BaseException extends Exception
{   
	// 默认HTTP状态码
	public $code = 400;

	// 默认错误提示信息
	public $msg = '参数错误';

	// 默认业务错误码
	public $errorCode = 10000;


	// 构造函数
	public function __construct($params = [])
	{
		// 判断是否数组
		if(!is_array($params)){
		  return;
		}

		// 判断是否有code、errorCode、msg这些参数代入
		if(array_key_exists('code',$params)){
		  $this->code = $params['code'];
		}
		if(array_key_exists('msg',$params)){
		  $this->msg = $params['msg'];
		}
		if(array_key_exists('errorCode',$params)){
		  $this->errorCode = $params['errorCode'];
		}
        
    }
}



具体异常处理类

1)新建对应异常类,继承BaseException。

2)定义具体的异常错误属性。


namespace app\lib\exception;


class BannerMissException extends BaseException
{
	// HTTP状态码
	public $code = 404;

	// 提示错误信息
	public $msg = '请求的banner不存在';

	// 自定义错误码
	public $errorCode = 40000;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值