laravel返回统一格式错误码问题
背景
最近在学习开发一个安卓项目,后端接口项目开始用PHP的Yii2.0框架新启了个项目,后换成laravel5.5,最近看到laravel升级了新版本,于是又将项目更新到laravel6.4
在使用yii和laravel的过程中,两个框架对web-api都非常友好,也都对restful做了不同程度的支持,但是还是遇到了一些问题,下面以laravel6.4为例,简单描述下我遇到的问题。
问题一:访问接口返回页面代码
最典型的就是laravelnew一个项目后,在浏览器直接访问localhost会进入laravel框架模版的默认欢迎页,这个没有太大的问题,问题就是你用postman把这个地址当接口
调用,返回的就是页面的代码,你在安卓端调用返回的还是页面的代码,其实实际使用不会去调用/跟接口,但是调用接口的时候一些其他的错误比如4xx,5xx都会返回html代码。
安卓端只能通过判断状态码来判断请求的成功失败,而且极难拿到错误信息。其实这里可以在安卓端统一加header,但是......于是网上查了下怎么处理
第一种办法解决postman调试的是可以在postman的请求中设置headersX-Requested-With:XMLHttpRequest来模拟ajax请求
第二种办法使项目仅返回JSON格式的需要新建一个Middleware
namespaceApp\Http\Middleware; useClosure; classJsonApplication { publicfunctionhandle($request,Closure$next) { $request->headers->set('Accept','application/json'); return$next($request); } }
然后在Kernel中全局注册Middleware并应用所有的api请求(这里因为项目是web-api项目,所以将routes/api.php的namespace去掉了,所以$middlewareGroups中的key是api)
namespaceApp\Http; useIlluminate\Foundation\Http\KernelasHttpKernel; classKernelextendsHttpKernel { 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*.*.* publicenumErrorCode{ OK("ok",0), PARAM_ERROR("paramerror",88888), UNKNOWN_ERROR("unknownerror",99999); ErrorCode(Stringvalue,Integerkey){ this.value=value; this.key=key; } privateStringvalue; privateIntegerkey; publicStringgetValue(){ returnvalue; } publicIntegergetKey(){ returnkey; } }
异常类
package*.*.*; import*.*.*.ErrorCode; publicclassApiExceptionextendsException{ publicintcode=0; publicApiException(ErrorCodeerrorCode){ super(errorCode.getValue()); this.code=errorCode.getKey(); } ...... }
使用
thrownewApiException(ErrorCode.UNKNOWN_ERROR);
于是查了下PHP的枚举,还真支持,但仔细一研究才发现,PHP的枚举不仅要安装开启SPL,然而提供的方法也并没有什么卵用
于是仿照JAVA写了一个
基类
namespaceApp\Enums; abstractclassEnum { publicstaticfunction__callStatic($name,$arguments) { returnnewstatic(constant('static::'.$name)); } }
错误码这里因为用到了魔术方法,所以要在注视中标注
namespaceApp\Enums; /** *@methodstaticCodeEnumOK *@methodstaticCodeEnumERROR */ classCodeEnumextendsEnum { publicconstOK=['0','ok']; publicconstERROR=['99999','fail']; private$code; private$msg; publicfunction__construct($param) { $this->code=reset($param); $this->msg=end($param); } publicfunctiongetCode() { return$this->code; } publicfunctiongetMsg() { return$this->msg; } }
自定义异常类
namespaceApp\Exceptions; useApp\Enums\CodeEnum; useException; useIlluminate\Support\Facades\Log; classApiExceptionextendsException { publicfunction__construct(CodeEnum$enum) { parent::__construct($enum->getMsg(),$enum->getCode()); } publicfunctionreport() { Log::error("ApiException{$this->getFile()}({$this->getLine()}):code({$this->getCode()})msg({$this->getMessage()})"); } publicfunctionrender($request) { returnresponse([ 'code'=>$this->getCode(), 'msg'=>$this->getMessage(), 'data'=>'' ]); } }
调用
thrownewApiException(newCodeEnum(CodeEnum::ERROR));//这样调总感觉不太好看 thrownewApiException(CodeEnum::OK());//这样调用和java的调用方式就很像了
总结
以上所述是小编给大家介绍的laravel返回统一格式错误码问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。