本文目录导读:

在Laravel中,响应宏(Response Macros)是一种优雅的方式,用于扩展框架的响应功能,下面详细介绍如何自定义响应宏:
创建响应宏
在 AppServiceProvider.php 中定义
<?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 = null, $message = '操作成功', $code = 200) {
return response()->json([
'code' => $code,
'message' => $message,
'data' => $data,
], $code);
});
// 错误响应宏
Response::macro('error', function ($message = '操作失败', $code = 400, $data = null) {
return response()->json([
'code' => $code,
'message' => $message,
'data' => $data,
], $code);
});
// 分页响应宏
Response::macro('paginate', function ($items) {
return response()->json([
'code' => 200,
'message' => '获取成功',
'data' => [
'items' => $items->items(),
'current_page' => $items->currentPage(),
'last_page' => $items->lastPage(),
'per_page' => $items->perPage(),
'total' => $items->total(),
]
]);
});
}
}
创建独立文件管理宏
创建 app/Support/Response/Macros.php
<?php
namespace App\Support\Response;
use Illuminate\Support\Facades\Response;
class Macros
{
public static function register()
{
Response::macro('success', function ($data = null, $message = '操作成功', $code = 200) {
return response()->json([
'status' => 'success',
'code' => $code,
'message' => $message,
'data' => $data,
]);
});
Response::macro('error', function ($message = '操作失败', $code = 400) {
return response()->json([
'status' => 'error',
'code' => $code,
'message' => $message,
], $code);
});
Response::macro('created', function ($data = null, $message = '创建成功') {
return response()->json([
'status' => 'success',
'code' => 201,
'message' => $message,
'data' => $data,
], 201);
});
}
}
在 AppServiceProvider 中调用
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Support\Response\Macros;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Macros::register();
}
}
在实际项目中使用
控制器中的使用示例
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$users = User::paginate(10);
// 返回成功响应
return response()->success($users);
}
public function store(Request $request)
{
try {
$user = User::create($request->validated());
// 返回创建成功
return response()->created($user);
} catch (\Exception $e) {
// 返回错误
return response()->error('用户创建失败', 500);
}
}
public function show($id)
{
try {
$user = User::findOrFail($id);
// 自定义参数
return response()->success($user, '用户详情获取成功', 200);
} catch (\Exception $e) {
// 返回404错误
return response()->error('用户不存在', 404);
}
}
public function update(Request $request, $id)
{
$user = User::find($id);
if (!$user) {
return response()->error('用户不存在', 404);
}
$user->update($request->all());
return response()->success($user, '用户更新成功');
}
public function destroy($id)
{
$user = User::find($id);
if (!$user) {
return response()->error('用户不存在', 404);
}
$user->delete();
return response()->success(null, '用户删除成功');
}
}
高级用法
支持附加头信息和分页数据
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
use Illuminate\Pagination\LengthAwarePaginator;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
// 带认证Token的响应
Response::macro('withToken', function ($data, $token, $message = '登录成功') {
return response()->json([
'success' => true,
'message' => $message,
'data' => $data,
'access_token' => $token,
'token_type' => 'Bearer',
]);
});
// 下载文件响应
Response::macro('downloadFile', function ($filePath, $fileName = null) {
if (!file_exists($filePath)) {
return response()->error('文件不存在', 404);
}
return response()->download($filePath, $fileName, [
'Content-Type' => 'application/octet-stream',
]);
});
// 处理Excel导出
Response::macro('excel', function ($data, $name = 'export.xlsx') {
return response()->streamDownload(function () use ($data) {
echo $data;
}, $name, ['Content-Type' => 'application/vnd.ms-excel']);
});
}
}
在中间件中使用
<?php
namespace App\Http\Middleware;
use Closure;
class ApiResponseMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
// 统一添加响应头
$response->header('X-API-Version', '1.0');
$response->header('X-Response-Time', microtime(true));
return $response;
}
}
最佳实践建议
统一响应结构规范
// 建议统一响应格式
{
"code": 200, // 业务状态码
"message": "成功", // 提示信息
"data": {}, // 数据内容
"timestamp": 1234567890 // 时间戳
}
创建响应宏基类
<?php
namespace App\Support\Response;
use Illuminate\Support\Facades\Response;
abstract class BaseResponse
{
protected static function format($code, $message, $data = null)
{
return [
'code' => $code,
'message' => $message,
'data' => $data,
'timestamp' => time()
];
}
}
注意事项
- 宏命名规范:使用动词开头,如
success、error、paginate - 参数默认值:为参数设置合理的默认值
- 类型提示:使用严格的类型提示
- 错误处理:在宏内部处理可能的异常
- 文档注释:为每个宏添加清晰的文档说明
这些响应宏可以显著提高代码复用性,统一API响应格式,让控制器代码更加简洁。