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

2025-05-29 0 34

背景

最近在学习开发一个安卓项目,后端接口项目开始用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

?

1

2

3

4

5

6

7

8

9

10
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)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
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的模式

?

1

2

3

4

5
{

"code": "0",

"msg": "ok",

"data": ""

}

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

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

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

枚举

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
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;

}

}

异常类

?

1

2

3

4

5

6

7

8

9

10
package *.*.*;

import *.*.*.ErrorCode;

public class ApiException extends Exception {

public int code = 0;

public ApiException(ErrorCode errorCode) {

super(errorCode.getValue());

this.code = errorCode.getKey();

}

......

}

使用

?

1
throw new ApiException(ErrorCode.UNKNOWN_ERROR);

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

于是仿照JAVA写了一个

基类

?

1

2

3

4

5

6

7

8
namespace App\\Enums;

abstract class Enum

{

public static function __callStatic($name, $arguments)

{

return new static(constant('static::' . $name));

}

}

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25
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;

}

}

自定义异常类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23
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' => ''

]);

}

}

调用

?

1

2
throw new ApiException(new CodeEnum(CodeEnum::ERROR)); // 这样调总感觉不太好看

throw new ApiException(CodeEnum::OK()); // 这样调用和java的调用方式就很像了

总结

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

原文链接:https://segmentfault.com/a/1190000020840188

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 laravel返回统一格式错误码问题 https://www.kuaiidc.com/91770.html

相关文章

发表评论
暂无评论