当前位置: 首页 > 后端技术 > PHP

Laravel返回统一格式的错误码

时间:2023-03-29 19:21:54 PHP

背景最近在学习开发一个Android项目。后台界面项目开始使用PHP的Yii2.0框架开始新项目,后来换成laravel5.5。最近看到laravel升级了一个新的。版本,所以我把项目更新到了laravel6.4。在使用yii和laravel的过程中,这两个框架对web-api都非常友好,也不同程度的支持了restful,但是还是遇到了一些问题,下面以laravel6.4为例,简单描述一下问题我遇到了。问题一:访问接口返回的页面最典型的代码是laravelnew。一个项目后,在浏览器中直接访问localhost,会进入laravel框架模板默认的欢迎页面。这不是什么大问题。问题是你用postman把这个地址作为接口调用返回页面的代码。当你在Android端调用它时,它返回页面的代码。其实实际使用是不会调用/跟随接口的,只是在调用接口的时候会出现一些其他的错误如4xx、5xx等会返回html代码。Android端只能通过判断状态码来判断请求成功与否,获取错误信息的难度极大。其实在Android端可以统一添加headers,但是...于是上网查了一下怎么处理。解决postman调试的第一种方法是在postman请求中设置headersX-Requested-With:XMLHttpRequest模拟ajax请求第二种方法是让项目只返回JSON格式,需要新建一个MiddlewarenamespaceApp\Http\Middleware;useClosure;classJsonApplication{publicfunctionhandle($request,Closure$next){$request->headers->set('Accept','application/json');返回$next($request);然后在Kernel中全局注册Middleware,并应用所有的api请求(这里因为项目是web-api项目,routes/api.php的命名空间去掉了,所以$middlewareGroups中的key是api)namespaceApp\Http;使用Illuminate\Foundation\Http\Kernel作为HttpKernel;classKernelextendsHttpKernel{protected$middlewareGroups=['api'=>[......'json_application',],];protected$routeMiddleware=[......'json_application'=>\App\Http\Middleware\JsonApplication::class,];}这样配置之后就不用再担心调用接口了,返回什么给你的是页面代码。问题二:接口返回统一的JSON格式。通过上面的配置接口返回的数据是JSON格式的,但是如果继续开发,会发现还是需要通过HTTP状态码来判断是否成功,然后在返回接口中用不同的keyJSON。区别特别大,即使是同一个接口,成功的时候和失败的时候也会返回不同的KEY。这道题多是用到了返回相同格式的问题。由于之前为vue写过很多接口,所以还是使用之前的按键方式{"code":"0","msg":"ok","data":""}但是laravel中如何返回这种格式已经成为一个问题。上网查了好几次,都没有好的解决办法。大部分覆盖不完整,错误代码和错误信息都写在逻辑层。新加的,完全不知道有没有冲突。后来在BD和GG里找了很久,也尝试过使用laravel自带的异常机制和Middleware来处理,但还是不是很满意。用过JAVA的都知道,在java中处理错误码非常方便。直接定义一个枚举,把所有的错误码都写在里面。当抛出异常时,枚举作为参数传入。像这样枚举包*.*.*publicenumErrorCode{OK("ok",0),PARAM_ERROR("paramerror",88888),UNKNOWN_ERROR("unknownerror",99999);ErrorCode(Stringvalue,Integerkey){this.value=value;this.key=键;}私有字符串值;私钥;publicStringgetValue(){返回值;}publicIntegergetKey(){返回密钥;}}异常类包*.*.*;导入*.*.*.ErrorCode;公共类ApiException扩展异常{publicintcode=0;publicApiException(ErrorCodeerrorCode){super(errorCode.getValue());this.code=errorCode.getKey();}......}使用thrownewApiException(ErrorCode.UNKNOWN_ERROR);于是查了一下PHP的枚举,确实支持,但是仔细研究后发现PHP的枚举不仅需要安装并开启SPL,而且提供的方法并没有写一个基类命名空间App\Enums;抽象类枚举{publicstaticfunction__callStatic($name,$arguments){returnnewstatic(constant('static::'.$name));}}这里的错误代码使用了magic方法,所以需要在gaze中标记namespaceApp\Enums;/***@methodstaticCodeEnumOK*@methodstaticCodeEnumERROR*/classCodeEnumextendsEnum{publicconstOK=['0','ok'];publicconstERROR=['99999','失败'];私人$代码;私人$味精;公共函数__construct($param){$this->code=reset($param);$this->msg=end($param);}publicfunctiongetCode(){return$this->code;}publicfunctiongetMsg(){return$this->msg;}}自定义异常类命名空间App\Exceptions;useApp\Enums\CodeEnum;useException;useIlluminate\Support\Facades\Log;classApiExceptionextendsException{publicfunction__construct(CodeEnum$enum){parent::__construct($枚举->getMsg(),$枚举->getCode());}publicfunctionrender($request){returnresponse(['code'=>$this->getCode(),'msg'=>$this->getMessage(),'data'=>'']);}}调用thrownewApiException(新代码枚举(代码枚举::错误));//这种调整总是不太好看thrownewApiException(CodeEnum::OK());//这种调用方式和java很像,当然可能有人认为你写的是php。为什么总拿它和java比呢?这里没有比较。因为工作原因,日常工作中java和php都写。我将结合另一种语言的优点来使用php中的优点。用法也会想怎么用java来实现。上面的实现已经把源码放在了github上https://github.com/yinfuyuan/php-enum详细的使用方法也可以参考另一篇介绍的文章https://segmentfault.com/a/1190000022711880文末使用枚举结合laravel返回统一格式的错误码