laravel返回统一格式错误码问题
背景
最近在学习开发一个安卓项目,后端接口项目开始用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返回统一格式错误码问题,希望对大家有所帮助
上一篇: 嫩姜的贮存,你get到了吗?
推荐阅读
-
解决ASP.NET MVC返回的JsonResult 中 日期类型数据格式问题,和返回的属性名称转为“驼峰命名法”和循环引用问题
-
RestFul API 统一格式返回 + 全局异常处理
-
让Laravel API永远返回JSON格式响应的方法示例
-
快速解决处理后台返回json数据格式的问题
-
Laravel统一封装接口返回状态实例讲解
-
动态放入后台给的键值对显示出来,然后动态返回数据(难点:数据格式问题)
-
PHP使Laravel为JSON REST API返回自定义错误的问题
-
laravel返回统一格式错误码问题
-
只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常
-
java统一返回数据格式方法