PHP项目接口异常如何统一返回

wen PHP项目 22

本文目录导读:

PHP项目接口异常如何统一返回

  1. 基于异常处理的统一返回方案(推荐)
  2. 中间件方案(适用于框架)
  3. 简单实用的统一处理类
  4. 使用示例
  5. 响应格式建议
  6. 推荐方案选择

在PHP项目中统一处理接口异常返回,通常有几种常见且推荐的做法,以下是几种成熟的解决方案:

基于异常处理的统一返回方案(推荐)

自定义异常类

<?php
// App\Exceptions\ApiException.php
class ApiException extends \Exception
{
    protected $statusCode;
    protected $data;
    public function __construct($message = "", $code = 0, $statusCode = 400, $data = null)
    {
        parent::__construct($message, $code);
        $this->statusCode = $statusCode;
        $this->data = $data;
    }
    public function getStatusCode()
    {
        return $this->statusCode;
    }
    public function getData()
    {
        return $this->data;
    }
}

统一响应类

<?php
// App\Http\Response\ApiResponse.php
class ApiResponse
{
    public static function success($data = null, $message = 'Success', $code = 200)
    {
        return json_encode([
            'code' => $code,
            'message' => $message,
            'data' => $data,
            'timestamp' => time()
        ]);
    }
    public static function error($message = 'Error', $code = 400, $data = null)
    {
        return json_encode([
            'code' => $code,
            'message' => $message,
            'data' => $data,
            'timestamp' => time()
        ]);
    }
    public static function exception(\Exception $exception)
    {
        $code = $exception->getCode() ?: 500;
        $message = $exception->getMessage() ?: 'Internal Server Error';
        // 生产环境隐藏错误详情
        if (env('APP_ENV') === 'production') {
            $message = 'Internal Server Error';
        }
        return self::error($message, $code);
    }
}

全局异常处理器

<?php
// App\Exceptions\Handler.php
class Handler
{
    public function render($request, \Exception $exception)
    {
        // 如果是API请求
        if ($this->isApiRequest($request)) {
            // 自定义异常处理
            if ($exception instanceof ApiException) {
                return ApiResponse::exception($exception);
            }
            // 其他异常处理
            return ApiResponse::exception($exception);
        }
        // 非API请求交给默认处理
        return parent::render($request, $exception);
    }
    private function isApiRequest($request)
    {
        return $request->expectsJson() || 
               strpos($request->path(), 'api/') === 0;
    }
}

中间件方案(适用于框架)

Laravel 示例

<?php
// app/Http/Middleware/ApiResponseMiddleware.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\JsonResponse;
class ApiResponseMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        // 只处理API路由
        if ($request->is('api/*')) {
            return $this->formatResponse($response);
        }
        return $response;
    }
    protected function formatResponse($response)
    {
        if ($response instanceof JsonResponse) {
            $original = $response->getData(true);
            // 统一包装响应格式
            $formatted = [
                'code' => $response->getStatusCode(),
                'message' => $original['message'] ?? 'Success',
                'data' => $original['data'] ?? $original,
                'timestamp' => time()
            ];
            return response()->json($formatted);
        }
        return $response;
    }
}

简单实用的统一处理类

<?php
// App\Helpers\ApiHelper.php
class ApiHelper
{
    // 成功响应
    public static function success($data = [], $message = '操作成功')
    {
        return self::response(200, $message, $data);
    }
    // 错误响应
    public static function error($message = '操作失败', $code = 400, $data = [])
    {
        return self::response($code, $message, $data);
    }
    // 未授权
    public static function unauthorized($message = '未授权访问')
    {
        return self::response(401, $message);
    }
    // 参数错误
    public static function validationError($errors = [])
    {
        return self::response(422, '参数验证失败', $errors);
    }
    // 服务器错误
    public static function serverError($message = '服务器内部错误')
    {
        return self::response(500, $message);
    }
    // 基础响应方法
    private static function response($code, $message, $data = null)
    {
        $response = [
            'code' => $code,
            'message' => $message,
            'data' => $data,
            'timestamp' => time()
        ];
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($response, JSON_UNESCAPED_UNICODE);
        exit;
    }
}

使用示例

<?php
// 控制器中使用
class UserController
{
    public function login()
    {
        try {
            // 业务逻辑
            $user = User::find($id);
            if (!$user) {
                // 触发自定义异常
                throw new ApiException('用户不存在', 1001, 404);
            }
            // 成功返回
            return ApiHelper::success($user, '登录成功');
        } catch (ApiException $e) {
            // 自定义异常处理
            return ApiHelper::error($e->getMessage(), $e->getCode());
        } catch (\Exception $e) {
            // 其他异常处理
            Log::error($e->getMessage());
            return ApiHelper::serverError();
        }
    }
    public function validate()
    {
        // 验证失败示例
        $errors = ['name' => '用户名不能为空'];
        return ApiHelper::validationError($errors);
    }
}

响应格式建议

{
    "code": 200,
    "message": "成功",
    "data": {
        "user": {
            "id": 1,
            "name": "张三"
        }
    },
    "timestamp": 1620000000
}

推荐方案选择

  1. 小型项目:使用 ApiHelper 简单类,直接调用静态方法
  2. 中大型项目:使用自定义异常 + 全局异常处理器
  3. 框架项目:使用中间件方案,统一拦截处理

这样设计的好处:

  • 统一的错误格式
  • 便于前端统一处理
  • 代码复用性高
  • 易于维护和扩展

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