laravel返回統(tǒng)一格式錯誤碼問題
背景
最近在學習開發(fā)一個安卓項目,后端接口項目開始用PHP的Yii2.0框架新啟了個項目,后換成laravel5.5,最近看到laravel升級了新版本,于是又將項目更新到laravel6.4
在使用yii和laravel的過程中,兩個框架對web-api都非常友好,也都對restful做了不同程度的支持,但是還是遇到了一些問題,下面以laravel6.4為例,簡單描述下我遇到的問題。
問題一:訪問接口返回頁面代碼
最典型的就是laravel new 一個項目后,在瀏覽器直接訪問localhost會進入laravel框架模版的默認歡迎頁,這個沒有太大的問題,問題就是你用postman把這個地址當接口
調(diào)用,返回的就是頁面的代碼,你在安卓端調(diào)用返回的還是頁面的代碼,其實實際使用不會去調(diào)用/跟接口,但是調(diào)用接口的時候一些其他的錯誤比如4xx,5xx都會返回html代碼。
安卓端只能通過判斷狀態(tài)碼來判斷請求的成功失敗,而且極難拿到錯誤信息。其實這里可以在安卓端統(tǒng)一加header,但是...... 于是網(wǎng)上查了下怎么處理
第一種辦法解決postman調(diào)試的是可以在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, ]; }
這樣配置好后就再也不用擔心調(diào)用接口,給你返回的是頁面代碼。
問題二: 接口返回統(tǒng)一的JSON格式
通過上面的配置接口返回數(shù)據(jù)都是JSON的格式了,但是繼續(xù)開發(fā)會發(fā)現(xiàn),還是需要通過HTTP狀態(tài)碼來判斷是否成功,然后返回的JSON里面的key不同的接口差異特別大,即使同一個接口在成功和出錯的時候也會返回不同的KEY。
這個問題多采用返回同一格式的問題,由于之前給vue寫過很多接口,所以還是沿用之前的key的模式
{ "code": "0", "msg": "ok", "data": "" }
但是在laravel中怎么返回這個格式成了一個問題,網(wǎng)上查了好幾次,都沒有太好的解決辦法,多是覆蓋的情況不全,再有就是錯誤碼錯誤信息都寫在邏輯層,新加的完全不知道有沒有沖突。
后來又在BD和GG搜索好久,自己也嘗試用laravel自帶的異常機制和Middleware處理,始終不是太滿意。
用過JAVA的都知道,在java中處理錯誤碼很方便,直接定義一個枚舉把所有的錯誤代碼都寫在里面,拋出異常的時候枚舉當做參數(shù)傳遞進去。類似于這樣
枚舉
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的枚舉,還真支持,但仔細一研究才發(fā)現(xiàn),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' => '' ]); } }
調(diào)用
throw new ApiException(new CodeEnum(CodeEnum::ERROR)); // 這樣調(diào)總感覺不太好看 throw new ApiException(CodeEnum::OK()); // 這樣調(diào)用和java的調(diào)用方式就很像了
總結
以上所述是小編給大家介紹的laravel返回統(tǒng)一格式錯誤碼問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
相關文章
php實現(xiàn)的IMEI限制的短信驗證碼發(fā)送類
本文給大家分享的是可以檢驗手機號碼與IMEI的短信驗證碼發(fā)送的php類,十分的實用,這里推薦給大家,有需要的小伙伴可以參考下。2015-05-05PHP中用mysqli面向?qū)ο蟠蜷_連接關閉mysql數(shù)據(jù)庫的方法
下面小編就為大家?guī)硪黄狿HP中用mysqli面向?qū)ο蟠蜷_連接關閉mysql數(shù)據(jù)庫的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11thinkPHP框架實現(xiàn)類似java過濾器的簡單方法示例
這篇文章主要介紹了thinkPHP框架實現(xiàn)類似java過濾器的簡單方法,結合實例形式分析了thinkPHP基于繼承實現(xiàn)的登錄驗證功能相關操作方法,需要的朋友可以參考下2018-09-09Zend Framework框架的session會話周期及次數(shù)限制使用示例
這篇文章主要介紹了Zend Framework框架的session會話周期及次數(shù)限制使用示例,需要的朋友可以參考下2014-03-03Yii2中hasOne、hasMany及多對多關聯(lián)查詢的用法詳解
hasOne、hasMany是Yii2特有的用于多表關聯(lián)查詢的函數(shù),平時在使用多表關聯(lián)查詢的時候建議使用它們。這篇文章主要介紹了Yii2中hasOne、hasMany及多對多關聯(lián)查詢的用法詳解,需要的朋友可以參考下2017-02-02PHP中數(shù)據(jù)庫單例模式的實現(xiàn)代碼分享
這篇文章主要介紹了PHP中數(shù)據(jù)庫單例模式的實現(xiàn)代碼分享,本文先是講解了單例模式的一些知識,然后給出了數(shù)據(jù)庫單例模式實現(xiàn)代碼,需要的朋友可以參考下2014-08-08