本文目录导读:

在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());
}
}
注意事项
- 注册时机:响应宏必须在请求处理前注册,
AppServiceProvider的boot()方法是合适的位置 - 命名冲突:避免与 Laravel 内置方法冲突
- 返回类型:确保宏返回
Illuminate\Http\JsonResponse或Illuminate\Http\Response实例 - 依赖注入:宏中可以使用依赖注入,但需要通过闭包参数传入
通过自定义响应宏,你可以统一 API 响应格式,减少重复代码,提高开发效率。