PHP提供 Exception 类来处理异常

new Exception('错误信息(默认为空)','错误代码(默认0)','异常链中前一个异常')

然后可以通过

e -> getMessage() 获取异常信息
e -> getCode() 获取异常错误码

处理异常

        try {
//可能抛出异常代码
throw new Exception("Error Processing Request", 1);
} catch (Exception $e) {
// 1. 记录日志
// 2. 处理异常,程序继续进行 / 继续向上抛出异常 / 终止程序,打印异常错误
}

在ThinkPHP中,框架自带异常处理类,返回错误信息以HTML页面形式展示,如果程序出现错误开发人员没有主动捕捉异常,则会被框架捕捉,然后抛出HTML

当在接口设计中时,由于无法得知客户端类型,所以HTML的形式客户端可能无法解析,此时便需要重写异常类,以json的形式返回错误信息给客户端

异常分类:

  • 自定义异常:通常是由客户端传递参数错误导致,此类异常不需要记录日志,但需要返回错误原因
  • 服务器异常:代码错误导致异常,此类异常需要记录日志,但不需要返回错误原因

服务器异常错误一般由PHP或者框架抛出,自定义异常需要手动捕捉,然后抛出

实现:

在Application/common目录下新建 exception 目录,此目录为异常类库目录

Application/common/exception/ExceptionHandler (重写后的异常处理类)

<?php
namespace app\common\exception; use Exception;
use think\exception\Handle;
use think\facade\Request;
use think\Log; class ExceptionHandler extends Handle { private $code;
private $msg;
private $errorCode; public function render(Exception $e) {
if ($e instanceof BaseException) {
//如果是自定义异常,则控制http状态码,不需要记录日志
//因为这些通常是因为客户端传递参数错误或者是用户请求造成的异常
//不应当记录日志 $this->code = $e->code;
$this->msg = $e->msg;
$this->errorCode = $e->errorCode;
} else {
// 如果是服务器未处理的异常,将http状态码设置为500,并记录日志
if (config('app_debug')) {
// 调试状态下需要显示TP默认的异常页面,因为TP的默认页面
// 很容易看出问题
return parent::render($e);
} $this->code = 500;
$this->msg = 'sorry,we make a mistake. (^o^)Y';
$this->errorCode = 999;
$this->recordErrorLog($e);
} $request = Request::instance();
$result = [
'msg' => $this->msg,
'error_code' => $this->errorCode,
'request_url' => $request = $request->url(),
];
return json($result, $this->code);
} /*
* 将异常写入日志
*/
private function recordErrorLog(Exception $e) {
Log::init([
'type' => 'File',
'path' => LOG_PATH,
'level' => ['error'],
]);
Log::record($e->getMessage(), 'error');
} }

这个类会判断异常来源,并作出相应处理

创建处理类后,需要修改对应配置文件,让这个类成为框架默认异常处理类

在application/config/app.php

    // 异常处理handle类 留空使用 \think\exception\Handle
'exception_handle' => '\app\common\exception\ExceptionHandler',

Application/common/exception/BaseException (自定义异常类基类,基础PHP自带异常类Exception)

<?php
namespace app\common\exception;
use think\Exception; /**
* Class BaseException
* 自定义异常类的基类
*/
class BaseException extends Exception {
public $code = 400;
public $msg = 'invalid parameters';
public $errorCode = 999; /**
* 构造函数,接收一个关联数组
* @param array $params 关联数组只应包含code、msg和errorCode,且不应该是空值
*/
public function __construct($params = []) {
if (!is_array($params)) {
return;
}
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'];
}
}
}

自定义异常类

Application/common/exception/UserException (自定义异常,这里举例User模块的异常)

<?php

namespace app\common\exception;

class UserException extends BaseException {
public $code = 404;
public $msg = '用户不存在';
public $errorCode = 60000;
}

抛出自定义异常

    try {
//todo...
throw new \app\common\exception\UserException(); } catch (Exception $e) { }

此时异常展示不再是TP自带的HTML页,而是

{
"msg": "用户不存在",
"error_code": 60000,
"request_url": "/wx_shop/public/index.php/admin/banner/list"
}

  

PHP/TP5 接口设计中异常处理的更多相关文章

  1. 【RESTful风格】软件接口设计中RESTful风格

    REST = Representational State Transfer 表述性状态转移,是一种软甲接口设计风格.总之就是一种风格 REST基于:HTTP.HTML.JSON.XML.URI 这些 ...

  2. API 接口设计中 Token 类型的分类与设计

    在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等 其中,在所有的服务设计中,都不可避免的涉及到Token的设计. 目前,基 ...

  3. python接口设计中的__all__和del

    最近在实现python接口中遇到了一些小问题,解决后总结如下. 目的:在设计接口时,只暴露某个文件的特定方法. 例如: t.py import os import sys def a(): pass ...

  4. TP5接口开发之异常处理接管

    前几天在开发的时候用到了第三方的扩展包,使用过程中第三方扩展包抛出了异常 因为这边是接口开发,需要返回错误代码以及提示信息等,所以就需要接管异常处理. 此文章只做笔记,有不对或不详细的地方欢迎大家留言 ...

  5. 在Java API设计中,面向接口编程的思想,以及接口和工厂的关系

    现在的java API的设计中,提倡面向接口的编程,即在API的设计中,参数的传递和返回建议使用接口,而不是具体的实现类,如一个方法的输入参数类型应该使用Map接口,而不是HashMap或Hashta ...

  6. C++ 11可变参数接口设计在模板编程中应用的一点点总结

    概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...

  7. 针对接口编程能帮助达到面向对象开发和设计中"低耦合"的要求. 某公司...打印机...(笔试中遇到的题目)

    针对接口编程能帮助达到面向对象开发和设计中"低耦合"的要求.         举个例子:某公司有一台特殊打印机,还可以使用一年,一年后可能换为另一种打印机,这两种打印机都特殊而贵. ...

  8. RESTful接口设计原则/最佳实践(学习笔记)

    RESTful接口设计原则/最佳实践(学习笔记) 原文地址:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 1 ...

  9. Web API接口设计经验总结

    在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔<Web API应用架构在Winform混合框架中的应用(1)>.<Web API应用架构在Winfo ...

随机推荐

  1. django 简易版搭建

    1.根目录下创建mysql.cnf文件 [client]database = identimguser = rootpassword = roothost = 127.0.0.1port = 3306 ...

  2. video自动填充满父级元素

    想要video能自动填充慢父div的大小,只要给video标签加上style="width= 100%; height=100%; object-fit: fill"即可. obj ...

  3. 读取Excel表格中数据原型

    写下这篇博客来记录自己的工作,这部分功能是读取Excel表格中的数据,并通过c#中的datagridview控件将读取的数据显示出来.为了方便用户,我设计了一个read按钮,用户点击这个按钮,会弹出打 ...

  4. python int str

    1. int 类型转换 a = "123" b = int(a) b = b+10 print(type(a),a) print(type(b),b) 2. int(num,bas ...

  5. day02python 整型 布尔

    今日内容 int bool 详细内容 1.整型(int) Py2 32位电脑 64位电脑 超出范围后python将自动转换成long(长整型) /运算不能显示小数-> (整形除法只能保留整数位) ...

  6. Linux 练习题(2)

    3.  请使用命令行展开功能来完成以下练习:      (1). 创建/tmp目录下的:a_c, a_d, b_c, b_d [root@db146 ~]# mkdir /tmp/{a,b}_{c,d ...

  7. vue实现淘宝购物车功能

    淘宝购物车功能,效果如下图 非常简单的逻辑,没有做代码的封装,代码如下 <div class="list-container"> <div class=" ...

  8. 第二节《Git暂存区》

    在上一节中我们的demo版本库经历了一次提交,我们可以使用git og --stat查看一下提交日志. [root@git demo]# git log --statcommit 986a1bd458 ...

  9. CSVN配置自动备份策略

    在浏览器中登录CSVN管理页面,登录地址就是ip:3343,版本库->backup schedule ,选择type of job(备份类型),when to run(备份频率和时间),numb ...

  10. jQuery 点击后退(返回)执行函数

    <html> <head> <meta charset="UTF-8"> <meta name="viewport" ...