大家好,我是专注 PHP 实战干货的博主~前两天分享了开发效率工具、.gitignore 配置,今天给大家带来PHP 接口开发的核心规范:统一返回格式封装。做 PHP 接口开发,最忌讳返回格式混乱:有的接口返回{status:1, info:"成功", data:{}},有的返回{code:200, message:"失败", result:{}},前端对接崩溃,后端维护也麻烦。
这篇文章给大家封装了通用的接口返回类 + Trait 复用方案,标准化 code/msg/data 结构,成功、失败、异常一键调用,直接复制到项目就能用,新手也能写出大厂级规范接口。
先统一所有接口的返回格式,核心包含 3 个字段,所有场景通用: | | |
|---|
| | 状态码(200 = 成功,非 200 = 失败 / 异常) |
| | |
| | |
示例:
- 成功返回
:
{ "code": 200, "msg": "操作成功", "data": { "id": 1, "name": "关注我,每天分享PHP实战干货" }}
失败返回
:{ "code": 400, "msg": "检测到粉丝未点赞和关注,终止交易", "data": []}
异常返回
:{ "code": 500, "msg": "服务器内部错误:有粉丝连夜跑路了", "data": []}
适合所有 PHP 项目(Laravel/ThinkPHP/ 原生),封装成独立类,全局调用:
第一步:创建返回类文件
在项目的 app/common/ 目录下新建 Response.php(目录可自定义,确保自动加载):
<?phpnamespace app\common;/** * PHP 接口统一返回格式封装类 * 可直接复制到项目中使用 */classResponse{ /** * 成功返回 * @param array|object $data 业务数据 * @param string $msg 提示信息 * @param int $code 状态码 * @return \Illuminate\Http\JsonResponse|string */ public static functionsuccess($data = [], $msg = '操作成功', $code = 200) { $result = [ 'code' => $code, 'msg' => $msg, 'data' => $data ]; // 兼容Laravel/ThinkPHP/原生PHP if(function_exists('json')) { // ThinkPHP 框架 return json($result); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { // Laravel 框架 return response()->json($result); } else { // 原生PHP header('Content-Type: application/json; charset=utf-8'); return json_encode($result, JSON_UNESCAPED_UNICODE); } } /** * 失败返回 * @param string $msg 提示信息 * @param int $code 状态码 * @param array $data 附加数据 * @return \Illuminate\Http\JsonResponse|string */ public static functionfail($msg = '操作失败', $code = 400, $data = []) { $result = [ 'code' => $code, 'msg' => $msg, 'data' => $data ]; if(function_exists('json')) { return json($result); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { return response()->json($result); } else { header('Content-Type: application/json; charset=utf-8'); return json_encode($result, JSON_UNESCAPED_UNICODE); } } /** * 异常返回 * @param \Exception $e 异常对象 * @param int $code 状态码 * @return \Illuminate\Http\JsonResponse|string */ public static functionerror(\Exception$e, $code = 500) { // 生产环境隐藏具体异常信息 $msg = env('APP_ENV') == 'production' ? '服务器内部错误' : '服务器内部错误:' . $e->getMessage() . '(行:' . $e->getLine() . ')'; $result = [ 'code' => $code, 'msg' => $msg, 'data' => [] ]; if(function_exists('json')) { return json($result); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { return response()->json($result); } else { header('Content-Type: application/json; charset=utf-8'); return json_encode($result, JSON_UNESCAPED_UNICODE); } }}
<?phprequire_once 'app/common/Response.php';use app\common\Response;// 成功示例$userData = ['id' => 1, 'name' => 'PHP实战', 'email' => 'test@php.com'];echo Response::success($userData, '获取用户信息成功');// 失败示例// echo Response::fail('参数缺失:用户ID', 400);// 异常示例// try {// // 模拟数据库错误// throw new Exception('数据库连接失败');// } catch (Exception $e) {// echo Response::error($e);// }
<?phpnamespace app\api\controller;use app\common\Response;use think\Controller;classUserControllerextendsController{ // 获取用户信息接口 public functiongetUser() { $id = $this->request->param('id'); if(!$id) { return Response::fail('用户ID不能为空', 400); } // 模拟查询用户数据 $user = ['id' => $id, 'name' => 'PHP实战干货', 'age' => 28]; return Response::success($user, '获取用户信息成功'); }}
<?phpnamespace App\Http\Controllers\Api;use App\common\Response;use App\Http\Controllers\Controller;use Illuminate\Http\Request;classUserControllerextendsController{ public functiongetUser(Request $request) { $id = $request->input('id'); if(!$id) { return Response::fail('用户ID不能为空', 400); } $user = ['id' => $id, 'name' => 'PHP实战干货', 'age' => 28]; return Response::success($user, '获取用户信息成功'); }}
三、封装方案 2:Trait 复用(更灵活)
如果不想用独立类,可封装成 Trait,让控制器直接复用:
<?phpnamespace app\common\traits;/** * 接口返回 Trait * 控制器引入后可直接调用 success/fail/error 方法 */traitResponseTrait{ /** * 成功返回 */ protected functionsuccess($data = [], $msg = '操作成功', $code = 200) { $result = [ 'code' => $code, 'msg' => $msg, 'data' => $data ]; if(function_exists('json')) { return json($result); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { return response()->json($result); } else { header('Content-Type: application/json; charset=utf-8'); return json_encode($result, JSON_UNESCAPED_UNICODE); } } /** * 失败返回 */ protected functionfail($msg = '操作失败', $code = 400, $data = []) { $result = [ 'code' => $code, 'msg' => $msg, 'data' => $data ]; if(function_exists('json')) { return json($result); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { return response()->json($result); } else { header('Content-Type: application/json; charset=utf-8'); return json_encode($result, JSON_UNESCAPED_UNICODE); } } /** * 异常返回 */ protected functionerror(\Exception$e, $code = 500) { $msg = env('APP_ENV') == 'production' ? '服务器内部错误' : '服务器内部错误:' . $e->getMessage() . '(行:' . $e->getLine() . ')'; $result = [ 'code' => $code, 'msg' => $msg, 'data' => [] ]; if(function_exists('json')) { return json($result); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { return response()->json($result); } else { header('Content-Type: application/json; charset=utf-8'); return json_encode($result, JSON_UNESCAPED_UNICODE); } }}
<?phpnamespace app\api\controller;use app\common\traits\ResponseTrait;use think\Controller;classOrderControllerextendsController{ // 引入Trait use ResponseTrait; // 创建订单接口 public functioncreateOrder() { $params = $this->request->param(); // 校验参数 if(empty($params['goods_id'])) { // 直接调用Trait里的方法 return $this->fail('商品ID不能为空', 400); } // 模拟创建订单 $order = ['order_id' => 'ORD' . time(), 'amount' => 99.00]; return $this->success($order, '订单创建成功'); }}
坑 1:状态码乱用 → 比如用 0 表示成功、1 表示失败,建议统一用 HTTP 语义化状态码(200 成功、4xx 客户端错误、5xx 服务端错误);坑 2:生产环境返回具体异常信息 → 会泄露服务器路径、数据库信息等敏感内容,一定要判断环境,生产环境只返回 “服务器内部错误”;坑 3:data 字段类型不统一 → 成功返回数组、失败返回字符串,前端解析易出错,建议 data 始终返回数组 / 对象(空数据用 [])。最后整合完整的 Response 类,包含所有场景,直接复制到项目即可:<?phpnamespace app\common;/** * PHP 接口统一返回格式封装类 * 支持 Laravel/ThinkPHP/原生PHP * 可直接复制到项目中使用 */classResponse{ // 常用状态码定义(可扩展) const CODE_SUCCESS = 200; // 成功 const CODE_PARAM_ERROR = 400; // 参数错误 const CODE_UNAUTHORIZED = 401; // 未授权 const CODE_FORBIDDEN = 403; // 禁止访问 const CODE_NOT_FOUND = 404; // 资源不存在 const CODE_SERVER_ERROR = 500; // 服务器错误 /** * 成功返回 * @param array|object $data 业务数据 * @param string $msg 提示信息 * @param int $code 状态码 * @return \Illuminate\Http\JsonResponse|string */ public static functionsuccess($data = [], $msg = '操作成功', $code = self::CODE_SUCCESS) { $result = [ 'code' => $code, 'msg' => $msg, 'data' => $data ]; return self::output($result); } /** * 失败返回 * @param string $msg 提示信息 * @param int $code 状态码 * @param array $data 附加数据 * @return \Illuminate\Http\JsonResponse|string */ public static functionfail($msg = '操作失败', $code = self::CODE_PARAM_ERROR, $data = []) { $result = [ 'code' => $code, 'msg' => $msg, 'data' => $data ]; return self::output($result); } /** * 异常返回 * @param \Exception $e 异常对象 * @param int $code 状态码 * @return \Illuminate\Http\JsonResponse|string */ public static functionerror(\Exception$e, $code = self::CODE_SERVER_ERROR) { // 生产环境隐藏具体异常信息 $msg = env('APP_ENV', 'production') == 'production' ? '服务器内部错误' : '服务器内部错误:' . $e->getMessage() . '(文件:' . $e->getFile() . ' 行:' . $e->getLine() . ')'; $result = [ 'code' => $code, 'msg' => $msg, 'data' => [] ]; return self::output($result); } /** * 统一输出JSON * @param array $result 结果数组 * @return \Illuminate\Http\JsonResponse|string */ private static functionoutput($result) { // 设置JSON编码参数 $options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK; if(function_exists('json')) { // ThinkPHP 框架 return json($result)->options($options); } elseif(class_exists('\Illuminate\Http\JsonResponse')) { // Laravel 框架 return response()->json($result, 200, [], $options); } else { // 原生PHP header('Content-Type: application/json; charset=utf-8'); return json_encode($result, $options); } }}
后续我会继续分享:PHP 开发规范、框架实战、架构思路、运维技巧、效率工具。关注我,每天 3 分钟,提升开发效率。欢迎在留言区告诉我:你平时写接口是自己封装返回格式,还是用框架自带的?有没有踩过返回格式的坑
?