PHP返回数据格式怎么统一

wen PHP项目 1

本文目录导读:

PHP返回数据格式怎么统一

  1. 方案一:JSON 格式(最推荐,适用于现代 Web 应用/API)
  2. 方案二:使用自定义类或 Trait(适合大型项目)
  3. 方案三:处理 HTTP 状态码
  4. 方案四:全局异常处理器(统一兜底)
  5. 总结建议

在PHP中统一返回数据格式是一个很好的实践,它能让前后端协作更顺畅,也便于后期的维护和扩展,下面提供几种常见且实用的统一方案:


JSON 格式(最推荐,适用于现代 Web 应用/API)

这是目前使用最广泛的方式,特别适合前后端分离的项目。

定义一个统一的返回函数

<?php
/**
 * 统一返回 JSON 数据格式
 *
 * @param int    $code    状态码(200 成功,400 参数错误,401 未登录,404 不存在,500 服务器错误)
 * @param string $message 提示信息
 * @param mixed  $data    业务数据(可选,默认 null)
 * @param array  $extra   额外字段(可选,用于扩展一些头信息等)
 * @return \Illuminate\Http\JsonResponse|\think\response\Json
 */
function apiResponse($code = 200, $message = 'success', $data = null, $extra = []) 
{
    // 1. 构建统一的数据结构
    $response = [
        'code'    => $code,      // 业务状态码
        'message' => $message,   // 提示信息
        'data'    => $data,      // 业务数据
        'timestamp' => time(),   // 时间戳,便于调试
    ];
    // 2. 如果有额外的自定义字段,合并进去
    $response = array_merge($response, $extra);
    // 3. 返回 JSON 响应
    return json($response); // Laravel 写法
    // 或者 return response()->json($response); // 通用 PHP 写法
    // 或者 return json_encode($response); // 纯 PHP 写法,需配合 header 设置
}

使用示例

// 成功返回(带数据)
return apiResponse(200, '获取成功', ['id' => 1, 'name' => '张三']);
// 成功返回(无数据)
return apiResponse(200, '删除成功');
// 失败返回
return apiResponse(400, '参数错误:username 不能为空');
// 未授权
return apiResponse(401, '请先登录');
// 服务器错误
return apiResponse(500, '系统繁忙,请稍后再试');

对应的前端解析

// 前端 fetch 或 axios 解析
fetch('/api/user/1')
  .then(res => res.json())
  .then(result => {
    if (result.code === 200) {
      console.log('成功:', result.data);
    } else {
      console.log('失败:', result.message);
    }
  });

使用自定义类或 Trait(适合大型项目)

可以将返回逻辑封装成类,更规范,也方便 IDE 提示。

<?php
namespace App\Traits;
trait ApiResponse
{
    /**
     * 成功响应
     */
    protected function success($data = null, $message = 'success', $code = 200)
    {
        return $this->response($code, $message, $data);
    }
    /**
     * 失败响应
     */
    protected function error($message = 'error', $code = 400, $data = null)
    {
        return $this->response($code, $message, $data);
    }
    /**
     * 核心响应方法
     */
    protected function response($code, $message, $data)
    {
        return response()->json([
            'code'    => $code,
            'message' => $message,
            'data'    => $data,
            'timestamp' => time(),
        ]);
    }
    /**
     * 列表分页响应(常用)
     */
    protected function paginate($paginator, $message = 'success')
    {
        return $this->success([
            'items' => $paginator->items(),
            'total' => $paginator->total(),
            'current_page' => $paginator->currentPage(),
            'per_page' => $paginator->perPage(),
            'last_page' => $paginator->lastPage(),
        ], $message);
    }
}

处理 HTTP 状态码

除了业务状态码,还应该将 HTTP 状态码与业务状态码对应起来,这样浏览器和前端都能正确识别。

场景 业务码 (code) HTTP 状态码
成功 200 200
参数校验失败 400 200/400
未登录/登录过期 401 200/401
无权限 403 200/403
资源不存在 404 200/404
服务器内部错误 500 200/500

注意: 通常业务码用于前端逻辑判断,HTTP 状态码用于浏览器和网络层面的判断,现在很多团队约定统一返回 200 HTTP 状态码 + 业务码,这样前端统一走 success 回调;也可以 HTTP 状态码和业务码都真实返回,前端捕获错误更规范。

// 推荐:两者都真实对应
public function login(Request $request)
{
    if (!auth()->attempt($request->only('email','password'))) {
        return response()->json([
            'code' => 401,
            'message' => '账号或密码错误',
            'data' => null,
        ], 401); // 同时设置 HTTP 状态码为 401
    }
    $user = auth()->user();
    return response()->json([
        'code' => 200,
        'message' => '登录成功',
        'data' => ['token' => $user->createToken('auth')->plainTextToken],
    ], 200);
}

全局异常处理器(统一兜底)

无论代码哪里出了异常,都统一走这个格式返回,避免散落的错误格式。

<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
    public function render($request, Throwable $e)
    {
        // 如果是 API 请求,统一返回 JSON
        if ($request->expectsJson() || $request->is('api/*')) {
            $code = $e->getCode() && in_array($e->getCode(), [200, 400, 401, 403, 404, 422, 500]) ? $e->getCode() : 500;
            return response()->json([
                'code'    => $code,
                'message' => $e->getMessage(),
                'data'    => null,
                'timestamp' => time(),
            ], $code === 500 ? 500 : 200); // 500 用真实 HTTP 状态码,其它统一 200
        }
        return parent::render($request, $e);
    }
}

总结建议

项目类型 推荐方案
前后端分离的 Web 应用 方案一 + 方案三(JSON + 业务码)
大型后台管理系统 方案二(Trait 方式)
高并发、微服务 API 方案一 + 引入统一 SDK 或中间件
所有项目 确保全局异常统一

核心要点:

  • code:业务状态码,用于前端逻辑判断
  • message:人类可读的提示信息
  • data:业务数据(成功)、null(失败)
  • timestamp:时间戳,便于排查问题
  • HTTP 状态码尽量与业务码一致或至少保证 500 的错误正确返回

抱歉,评论功能暂时关闭!