laravel返回统一格式错误码问题


Posted in PHP onNovember 04, 2019

背景

最近在学习开发一个安卓项目,后端接口项目开始用PHP的Yii2.0框架新启了个项目,后换成laravel5.5,最近看到laravel升级了新版本,于是又将项目更新到laravel6.4

在使用yii和laravel的过程中,两个框架对web-api都非常友好,也都对restful做了不同程度的支持,但是还是遇到了一些问题,下面以laravel6.4为例,简单描述下我遇到的问题。

问题一:访问接口返回页面代码

最典型的就是laravel new 一个项目后,在浏览器直接访问localhost会进入laravel框架模版的默认欢迎页,这个没有太大的问题,问题就是你用postman把这个地址当接口

调用,返回的就是页面的代码,你在安卓端调用返回的还是页面的代码,其实实际使用不会去调用/跟接口,但是调用接口的时候一些其他的错误比如4xx,5xx都会返回html代码。

安卓端只能通过判断状态码来判断请求的成功失败,而且极难拿到错误信息。其实这里可以在安卓端统一加header,但是...... 于是网上查了下怎么处理

第一种办法解决postman调试的是可以在postman的请求中设置headers X-Requested-With:XMLHttpRequest来模拟ajax请求

第二种办法使项目仅返回JSON格式的需要新建一个Middleware

namespace App\Http\Middleware;
use Closure;
class JsonApplication
{
  public function handle($request, Closure $next)
  {
    $request->headers->set('Accept', 'application/json');
    return $next($request);
  }
}

然后在Kernel中全局注册Middleware并应用所有的api请求(这里因为项目是web-api项目,所以将routes/api.php的namespace去掉了,所以$middlewareGroups中的key是api)

namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
  protected $middlewareGroups = [
    'api' => [
      ......
      'json_application',
    ],
  ];
  protected $routeMiddleware = [
    ......
    'json_application' => \App\Http\Middleware\JsonApplication::class,
  ];
}

这样配置好后就再也不用担心调用接口,给你返回的是页面代码。

问题二: 接口返回统一的JSON格式

通过上面的配置接口返回数据都是JSON的格式了,但是继续开发会发现,还是需要通过HTTP状态码来判断是否成功,然后返回的JSON里面的key不同的接口差异特别大,即使同一个接口在成功和出错的时候也会返回不同的KEY。

这个问题多采用返回同一格式的问题,由于之前给vue写过很多接口,所以还是沿用之前的key的模式

{
  "code": "0",
  "msg": "ok",
  "data": ""
}

但是在laravel中怎么返回这个格式成了一个问题,网上查了好几次,都没有太好的解决办法,多是覆盖的情况不全,再有就是错误码错误信息都写在逻辑层,新加的完全不知道有没有冲突。

后来又在BD和GG搜索好久,自己也尝试用laravel自带的异常机制和Middleware处理,始终不是太满意。

用过JAVA的都知道,在java中处理错误码很方便,直接定义一个枚举把所有的错误代码都写在里面,抛出异常的时候枚举当做参数传递进去。类似于这样

枚举

package *.*.*
public enum ErrorCode {
  OK("ok", 0),
  PARAM_ERROR("param error", 88888),
  UNKNOWN_ERROR("unknown error", 99999);
  ErrorCode(String value, Integer key) {
    this.value = value;
    this.key = key;
  }
  private String value;
  private Integer key;
  public String getValue() {
    return value;
  }
  public Integer getKey() {
    return key;
  }
}

异常类

package *.*.*;
import *.*.*.ErrorCode;
public class ApiException extends Exception {
  public int code = 0;
  public ApiException(ErrorCode errorCode) {
    super(errorCode.getValue());
    this.code = errorCode.getKey();
  }
  ......
}

使用

throw new ApiException(ErrorCode.UNKNOWN_ERROR);

于是查了下PHP的枚举,还真支持,但仔细一研究才发现,PHP的枚举不仅要安装开启SPL,然而提供的方法也并没有什么卵用

于是仿照JAVA写了一个

基类

namespace App\Enums;
abstract class Enum
{
  public static function __callStatic($name, $arguments)
  {
    return new static(constant('static::' . $name));
  }
}

错误码 这里因为用到了魔术方法,所以要在注视中标注

namespace App\Enums;
/**
 * @method static CodeEnum OK
 * @method static CodeEnum ERROR
 */
class CodeEnum extends Enum
{
  public const OK = ['0', 'ok'];
  public const ERROR = ['99999', 'fail'];
  private $code;
  private $msg;
  public function __construct($param)
  {
    $this->code = reset($param);
    $this->msg = end($param);
  }
  public function getCode()
  {
    return $this->code;
  }
  public function getMsg()
  {
    return $this->msg;
  }
}

自定义异常类

namespace App\Exceptions;
use App\Enums\CodeEnum;
use Exception;
use Illuminate\Support\Facades\Log;
class ApiException extends Exception
{
  public function __construct(CodeEnum $enum)
  {
    parent::__construct($enum->getMsg(), $enum->getCode());
  }
  public function report()
  {
    Log::error("ApiException {$this->getFile()}({$this->getLine()}): code({$this->getCode()}) msg({$this->getMessage()})");
  }
  public function render($request)
  {
    return response([
      'code' => $this->getCode(),
      'msg' => $this->getMessage(),
      'data' => ''
    ]);
  }
}

调用

throw new ApiException(new CodeEnum(CodeEnum::ERROR)); // 这样调总感觉不太好看
throw new ApiException(CodeEnum::OK()); // 这样调用和java的调用方式就很像了

总结

以上所述是小编给大家介绍的laravel返回统一格式错误码问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

PHP 相关文章推荐
PHP默认安装产生系统漏洞
Oct 09 PHP
用PHP的ob_start();控制您的浏览器cache!
Feb 14 PHP
php生成SessionID和图片校验码的思路和实现代码
Mar 10 PHP
php设计模式 Chain Of Responsibility (职责链模式)
Jun 26 PHP
一个PHP的QRcode类与大家分享
Nov 13 PHP
PHP判断指定时间段的2个方法
Mar 14 PHP
php结合ajax实现赞、顶、踩功能实例
May 12 PHP
CI框架在CLI下执行占用内存过大问题的解决方法
Jun 17 PHP
php数组函数array_walk用法示例
May 26 PHP
Laravel5.7 数据库操作迁移的实现方法
Apr 12 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
Oct 12 PHP
laravel 框架结合关联查询 when()用法分析
Nov 22 PHP
php 中self,this的区别和操作方法实例分析
Nov 04 #PHP
PHP 文件写入和读取操作实例详解【必看篇】
Nov 04 #PHP
PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
Nov 04 #PHP
php ZipArchive实现多文件打包下载实例
Oct 31 #PHP
Laravel框架实现抢红包功能示例
Oct 31 #PHP
laravel框架实现后台登录、退出功能示例
Oct 31 #PHP
TP5框架简单登录功能实现方法示例
Oct 31 #PHP
You might like
轻松修复Discuz!数据库
2008/05/03 PHP
php入门之连接mysql数据库的一个类
2012/04/21 PHP
一个非常完美的读写ini格式的PHP配置类分享
2015/02/12 PHP
浅谈PHP拦截器之__set()与__get()的理解与使用方法
2016/10/18 PHP
php可变长参数处理函数详解
2017/02/22 PHP
PHP的简单跳转提示的实现详解
2019/03/14 PHP
yii2 开发api接口时优雅的处理全局异常的方法
2019/05/14 PHP
Javascript中valueOf与toString区别浅析
2013/03/19 Javascript
利用ajaxfileupload插件实现文件上传无刷新的具体方法
2013/06/08 Javascript
javaScript实现浮点数转十六进制字符
2013/10/29 Javascript
使用简洁的jQuery方法实现隔行换色功能
2014/01/02 Javascript
JavaScript中的typeof操作符用法实例
2014/04/05 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
所见即所得的富文本编辑器bootstrap-wysiwyg使用方法详解
2016/05/27 Javascript
浅谈原生JS实现jQuery的animate()动画示例
2017/03/08 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
jQuery Position方法使用和兼容性
2017/08/23 jQuery
利用Node.js了解与测量HTTP所花费的时间详解
2017/09/22 Javascript
Javascript作用域和作用域链原理解析
2020/03/03 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
2021/01/22 Vue.js
Element el-button 按钮组件的使用详解
2021/02/01 Javascript
python局部赋值的规则
2013/03/07 Python
浅析Python 中整型对象存储的位置
2016/05/16 Python
Python科学计算之NumPy入门教程
2017/01/15 Python
Python爬虫之正则表达式基本用法实例分析
2018/08/08 Python
python 检查是否为中文字符串的方法
2018/12/28 Python
Python3.8.2安装包及安装教程图文详解(附安装包)
2020/11/28 Python
俄罗斯隐形眼镜和眼镜在线商店:Cronos
2020/06/02 全球购物
技校个人求职信范文
2014/01/25 职场文书
《莫泊桑拜师》教学反思
2014/04/23 职场文书
村党的群众路线教育实践活动工作总结
2014/10/25 职场文书
财务会计实训报告
2014/11/05 职场文书
css3 利用transform-origin 实现圆点分布在大圆上布局及旋转特效
2021/04/29 HTML / CSS
Python中else的三种使用场景
2021/06/16 Python
Windows11插耳机没反应怎么办? win11耳机没声音的多种解决办法
2021/11/21 数码科技
动画电影《擅长捉弄人的高木同学》6月10日上映!
2022/03/20 日漫