PHP/TP5 接口设计中异常处理
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 接口设计中异常处理的更多相关文章
- 【RESTful风格】软件接口设计中RESTful风格
REST = Representational State Transfer 表述性状态转移,是一种软甲接口设计风格.总之就是一种风格 REST基于:HTTP.HTML.JSON.XML.URI 这些 ...
- API 接口设计中 Token 类型的分类与设计
在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等 其中,在所有的服务设计中,都不可避免的涉及到Token的设计. 目前,基 ...
- python接口设计中的__all__和del
最近在实现python接口中遇到了一些小问题,解决后总结如下. 目的:在设计接口时,只暴露某个文件的特定方法. 例如: t.py import os import sys def a(): pass ...
- TP5接口开发之异常处理接管
前几天在开发的时候用到了第三方的扩展包,使用过程中第三方扩展包抛出了异常 因为这边是接口开发,需要返回错误代码以及提示信息等,所以就需要接管异常处理. 此文章只做笔记,有不对或不详细的地方欢迎大家留言 ...
- 在Java API设计中,面向接口编程的思想,以及接口和工厂的关系
现在的java API的设计中,提倡面向接口的编程,即在API的设计中,参数的传递和返回建议使用接口,而不是具体的实现类,如一个方法的输入参数类型应该使用Map接口,而不是HashMap或Hashta ...
- C++ 11可变参数接口设计在模板编程中应用的一点点总结
概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...
- 针对接口编程能帮助达到面向对象开发和设计中"低耦合"的要求. 某公司...打印机...(笔试中遇到的题目)
针对接口编程能帮助达到面向对象开发和设计中"低耦合"的要求. 举个例子:某公司有一台特殊打印机,还可以使用一年,一年后可能换为另一种打印机,这两种打印机都特殊而贵. ...
- RESTful接口设计原则/最佳实践(学习笔记)
RESTful接口设计原则/最佳实践(学习笔记) 原文地址:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 1 ...
- Web API接口设计经验总结
在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔<Web API应用架构在Winform混合框架中的应用(1)>.<Web API应用架构在Winfo ...
随机推荐
- Shell脚本的学习笔记一:变量
三种变量: 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量. 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需 ...
- linux之基础操作
- SQL注入之Sqli-labs系列第三十二关(基于宽字符逃逸注入)
开始挑战第三十二关(Bypass addslashes) 0x1查看源代码 (1)代码关键点 很明显,代码中利用正则匹配将 [ /,'," ]这些三个符号都过滤掉了 function che ...
- 二维数组的查找(JAVA)
二维数组查找 解题思路:找到该二维数组的特殊点,易知该二维数组左下角的那个点很特殊.从这个点往右看,数值都在变大:而往上看,数值都在变小.所以 我们可以将这个点的索引设为起点(i,j),当比目标数大时 ...
- webpack学习笔记(三)
访问网址: https://github.com/webpack/analyse "scripts": { "dev-build": "webpack ...
- python(二)——list、字典、字符串操作
列表——list 假设一种场景,想要存班里所有同学的名字,那应该拿什么存呢? 我们可以拿一个字符串去存,例如: stus = "s1,s2,s3,s4,s5……sn" 那我们要从里 ...
- CRM项目之stark组件
. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...
- edit this cookie chrome插件 (HttpAnalyzerStdV3 获取Cookie 后,再用edit this cookie添加cookie)
插件下载地址及安装方法:http://www.bkill.com/download/154494.html 博客提供下载地址:https://files.cnblogs.com/files/Fooo/ ...
- 【python】self & cls
转自 python中self,cls 普通的方法,第一个参数需要是self,它表示一个具体的实例本身. 如果用了staticmethod,那么就可以无视这个self,而将这个方法当成一个普通的函数使用 ...
- os.rename 和os.replace
f1 = open("hello.txt","w") f1.write("hello,my name is bobo.") f1.close ...