Laravel响应宏怎么自定义

wen PHP项目 2

本文目录导读:

Laravel响应宏怎么自定义

  1. 注册响应宏
  2. 使用响应宏
  3. 高级用法:带参数的动态宏
  4. 测试响应宏
  5. 注意事项

在Laravel中,响应宏(Response Macro)允许你自定义可复用的响应方法,以下是实现自定义响应宏的完整步骤:

注册响应宏

在 AppServiceProvider 中注册

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // 注册自定义响应宏
        Response::macro('success', function ($data = [], $message = '操作成功', $statusCode = 200) {
            return response()->json([
                'code' => $statusCode,
                'message' => $message,
                'data' => $data
            ], $statusCode);
        });
        Response::macro('error', function ($message = '操作失败', $statusCode = 400, $errors = []) {
            $response = [
                'code' => $statusCode,
                'message' => $message
            ];
            if (!empty($errors)) {
                $response['errors'] = $errors;
            }
            return response()->json($response, $statusCode);
        });
    }
}

创建独立的宏文件(推荐)

创建 app/Http/Response/ResponseMacros.php

<?php
namespace App\Http\Response;
use Illuminate\Support\Facades\Response;
class ResponseMacros
{
    public static function register()
    {
        Response::macro('success', function ($data = [], $message = '成功', $statusCode = 200) {
            return response()->json([
                'code' => 0,
                'message' => $message,
                'data' => $data
            ], $statusCode);
        });
        Response::macro('error', function ($message = '失败', $statusCode = 400, $errors = []) {
            $response = [
                'code' => $statusCode,
                'message' => $message
            ];
            if (!empty($errors)) {
                $response['errors'] = $errors;
            }
            return response()->json($response, $statusCode);
        });
        Response::macro('paginate', function ($data, $total = null) {
            return response()->json([
                'code' => 0,
                'message' => '成功',
                'data' => $data,
                'meta' => [
                    'total' => $total ?? $data->total(),
                    'per_page' => $data->perPage(),
                    'current_page' => $data->currentPage(),
                    'last_page' => $data->lastPage()
                ]
            ]);
        });
        Response::macro('created', function ($data = [], $message = '创建成功') {
            return response()->json([
                'code' => 201,
                'message' => $message,
                'data' => $data
            ], 201);
        });
        Response::macro('noContent', function () {
            return response()->json(null, 204);
        });
    }
}

然后在 AppServiceProvider 中注册:

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Http\Response\ResponseMacros;
class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        ResponseMacros::register();
    }
}

使用响应宏

在控制器或其他地方使用:

<?php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller
{
    public function index()
    {
        $users = User::paginate(10);
        // 使用自定义宏
        return response()->paginate($users);
    }
    public function store(Request $request)
    {
        $user = User::create($request->validated());
        // 使用成功响应
        return response()->success($user, '用户创建成功');
        // 或
        return response()->created($user, '用户创建成功');
    }
    public function show($id)
    {
        $user = User::find($id);
        if (!$user) {
            // 使用错误响应
            return response()->error('用户不存在', 404);
        }
        return response()->success($user);
    }
    public function update(Request $request, $id)
    {
        $user = User::find($id);
        if (!$user) {
            return response()->error('用户不存在', 404);
        }
        $user->update($request->validated());
        return response()->success($user, '更新成功');
    }
    public function destroy($id)
    {
        $user = User::find($id);
        if (!$user) {
            return response()->error('用户不存在', 404);
        }
        $user->delete();
        return response()->noContent();
    }
}

高级用法:带参数的动态宏

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // 动态状态码宏
        Response::macro('api', function ($data = null, $message = '', $statusCode = 200, $headers = []) {
            $response = [
                'code' => $statusCode,
                'message' => $message
            ];
            if (!is_null($data)) {
                $response['data'] = $data;
            }
            return response()->json($response, $statusCode, $headers);
        });
        // 异常处理宏
        Response::macro('exception', function (\Exception $e, $statusCode = 500) {
            return response()->json([
                'code' => $statusCode,
                'message' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine()
            ], $statusCode);
        });
        // 附带头信息的响应
        Response::macro('withHeaders', function ($data, $headers = []) {
            return response()->json($data)->withHeaders($headers);
        });
    }
}

测试响应宏

<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Support\Facades\Response;
class ResponseMacroTest extends TestCase
{
    public function test_success_response()
    {
        $response = $this->getJson('/api/users');
        $response->assertJson([
            'code' => 200,
            'message' => '成功',
            'data' => []
        ]);
    }
    public function test_custom_response()
    {
        $response = response()->success(['name' => 'John'], '自定义消息', 201);
        $this->assertEquals(201, $response->getStatusCode());
        $this->assertJson($response->getContent());
    }
}

注意事项

  1. 注册时机:响应宏必须在请求处理前注册,AppServiceProviderboot() 方法是合适的位置
  2. 命名冲突:避免与 Laravel 内置方法冲突
  3. 返回类型:确保宏返回 Illuminate\Http\JsonResponseIlluminate\Http\Response 实例
  4. 依赖注入:宏中可以使用依赖注入,但需要通过闭包参数传入

通过自定义响应宏,你可以统一 API 响应格式,减少重复代码,提高开发效率。

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