Thinkphp5.1 全局异常处理

0 评论 247 浏览

1. 封装统一返回类

<?php
/**
 * @author SHIH
 * @date 2020/10/14 10:06
 */

namespace app\utils;

use JsonSerializable;

/**
 * 返回结果封装
 * Class Result
 * @package app\utils
 */
class Result implements JsonSerializable {

    private $code;
    private $msg;
    private $data;

    /**
     * Result constructor.
     * @param int    $code
     * @param string $msg
     * @param string $data
     */
    public function __construct($code = 0, $msg = "success", $data = "") {
        $this->code = $code;
        $this->msg = $msg;
        $this->data = $data;
    }

    /**
     * 成功返回结果
     * @param string $data 返回数据
     * @return Result
     * @author SHIH
     * @date 2020/10/14 10:36
     */
    public static function ok($data = "") {
        return new self(0, "success", $data);
    }

    /**
     * 失败返回结果
     * @param array  $businessStatus BusinessStatus枚举值
     * @param string $data 返回数据
     * @return Result
     * @author SHIH
     * @date 2020/10/14 10:34
     */
    public static function fail($businessStatus, $data = "") {
        return new self($businessStatus[0], $businessStatus[1], $data);
    }

    public function __toString() {
        return json_encode($this);
    }

    /**
     * @return int
     */
    public function getCode() {
        return $this->code;
    }

    /**
     * @param int $code
     */
    public function setCode($code) {
        $this->code = $code;
    }

    /**
     * @return string
     */
    public function getMsg() {
        return $this->msg;
    }

    /**
     * @param string $msg
     */
    public function setMsg($msg) {
        $this->msg = $msg;
    }

    /**
     * @return string
     */
    public function getData() {
        return $this->data;
    }

    /**
     * @param string $data
     */
    public function setData($data) {
        $this->data = $data;
    }

    /**
     * 重写jsonSerialize
     * @return array|mixed
     * @author SHIH
     * @date 2020/11/21 9:58
     */
    public function jsonSerialize() {
        return [
            "code" => $this->getCode(),
            "msg"  => $this->getMsg(),
            "data" => $this->getData(),
        ];
    }
}

2. 封装业务异常状态

<?php
/**
 * 业务异常状态
 * @author SHIH
 * @date 2020/10/14 10:14
 */

namespace app\exception;


class BusinessStatus {

    /**
     * 成功,一切正常
     */
    const SUCCESS = [0, "success"];

    /**
     * 未登录或登录已过期,请重新登陆
     */
    const NOT_LOGIN = [401, "未登录或登录已过期,请重新登陆"];

    /**
     * 服务器错误
     */
    const UNKNOW_ERROR = [500, "服务器未知错误"];
}

3. 编写业务异常

<?php
/**
 * 业务异常
 * @author SHIH
 * @date 2020/10/14 9:14
 */

namespace app\exception;


use Exception;

class BusinessException extends Exception {

    /**
     * 异常数据信息
     * @var object|string
     */
    private $errData;

    /**
     * BusinessException constructor.
     * @param array  $businessStatus 异常状态及提示
     * @param object $data 异常数据信息
     */
    public function __construct($businessStatus, $data) {
        $this->errData = $data ? $data : "";
        parent::__construct($businessStatus[1], $businessStatus[0]);
    }

    /**
     * 获取异常数据
     * @return object|string
     */
    public function getErrData() {
        return $this->errData;
    }
}

4. 编写全局异常处理

自定义异常处理类需要继承thinkexceptionHandle并且实现render方法

参考文档:https://www.kancloud.cn/manual/thinkphp5_1/354092 异常处理接管部分

<?php
/**
 * 全局异常处理
 * @author SHIH
 * @date 2020/10/14 11:10
 */

namespace app\exception;

use Exception;
use app\utils\Result;
use think\exception\Handle;
use think\facade\Config;

class BusinessExceptionHandler extends Handle {

    public function render(Exception $exception) {
        if ($exception instanceof BusinessException) {
            $data = new Result($exception->getCode(), $exception->getMessage(), $exception->getErrData());
            return json($data, 200);
        } else if ($exception instanceof Exception) {
            $debugStatus = Config::get("app_debug");
            //开启debug状态,则非业务异常时会将trace信息放入data
            $errorData = $debugStatus ? $exception->getTrace() : '';
            $data = Result::fail(BusinessStatus::UNKNOW_ERROR, $errorData);
            $data->setMsg($exception->getMessage());
            return json($data, 200);
        }
        return parent::render($exception);
    }
}

5. 修改配置项

<?php

return [
    //...

    // 默认输出类型
    'default_return_type'    => 'json',

    //...

    // 异常处理handle类 留空使用 \think\exception\Handle
    'exception_handle'       => "\\app\\exception\\BusinessExceptionHandler",
];

6. 测试

<?php

namespace app\index\controller;

use app\exception\BusinessStatus;
use app\exception\BusinessException;
use app\utils\Result;

class Index {
    public function index() {
        echo "Hello,Thinkphp5.1";
    }

    public function exception() {
        //业务逻辑
        throw new BusinessException(BusinessStatus::NOT_LOGIN, ["key" => "val",]);
    }

    public function result() {
        //业务逻辑
        return Result::ok();
    }
}

访问index/index/exception
访问index/index/result

SHIH/thinkphp5.1-exception