我们先来梳理一下异常的分类:
tp5.1 有一个全局异常处理类,如果我们想自己实现上面的分类,需要覆盖和重写默认的全局异常处理类。
我们现在在 api 模块的同级下新建一个 lib 文件夹,再新建一个 exception 文件夹。
(我们想让这个 exception 里的类是一个通用的,可以供很多模块使用的一个类库。)
新建 ExceptionHandler 的 php class,并继承 Handle 类。
并且重新指定 tp5.1 的全局异常处理类:
在 config.php 文件中的 'exception_handle’字段输入我们自定义的处理器的命名空间:
app\lib\exception\ExceptionHandler
代码如下:
<?php
namespace app\lib\exception;
use think\exception\Handle;
class ExceptionHandler extends Handle {
public function render(Exception $e){ // 重写render方法
return json('是否重写成功');
}
}
User控制器代码:
public function getUserById($id)
{
(new IDMustBePositiveInt())->goCheck();
throw new \think\Exception('手动异常', 10006);
}
结果如下:
现在我们继续来写 render 方法来区分前面提到的两种异常:
其中有一种异常需要向客户端返回具体信息,我们在初始化对象的成员变量赋值最好的方式是通过构造函数来初始化赋值操作,更加符合面向对象的基本特性。则实例化的时候即可传入参数,相应的构造函数(父类中创建即可)会进行处理。需要新建一个 BaseException 类:
<?php
namespace app\lib\exception;
use Exception;
class BaseException extends Exception
{
public $code = 400; // HTTP 状态码 404,200...
public $msg = '参数错误'; // 错误信息具体
public $error_code = 10000; // 自定义错误码
public function __construct($params = [])
{
if (!is_array($params)) {
return; // 如果没有传入数组,那么就是使用默认的 code、msg 和 errorCode
}
if (array_key_exists('code', $params)) {
$this->code = $params['code'];
}
if (array_key_exists('msg', $params)) {
$this->msg = $params['msg'];
}
if (array_key_exists('error_code', $params)) {
$this->error_code = $params['error_code'];
}
}
}
只要是继承于 BaseException 的异常类都是我们自定义的类,且需要返回给客户端信息。
我们这样修改 render 方法:
<?php
namespace app\lib\exception;
use Exception;
use think\exception\Handle;
class ExceptionHandler extends Handle
{
private $code;
private $msg;
private $error_code;
public function render(Exception $e)
{
if ($e instanceof BaseException) {
$this->code = $e->code;
$this->msg = $e->msg;
$this->error_code = $e->error_code;
} else {
$this->code = 500;
$this->msg = '服务器内部异常';
$this->error_code = 999;
}
$request = request();
$result = [
'msg' => $this->msg,
'error_code' => $this->error_code,
'request_url' => $request->url()
];
return json($result, $this->code);
}
}
运行后发现:
我们来测试一下BaseException,User控制器代码为:
public function getUserById($id)
{
(new IDMustBePositiveInt())->goCheck();
throw new BaseException(); //抛出一个BaseException的异常
}
结果:
实现记录日志错误信息:
在config目录下,找到Log.php,开启一下配置信息:
在ExceptionHandler类render的方法下,写入记录日志代码:
Log::record($e->getMessage(),'error');
这里要注意引入
use think\facade\Log;
即可看到服务器内部异常时会记录日志
tp5 API 自定义全局异常处理(下)