本文目录导读:

在PHP中,中间件机制的最佳实践取决于你使用的框架(或是否自建),我来分享几种主流场景下的最佳用法:
现代框架中的中间件(以Laravel为例)
最佳实践:责任链模式 + 依赖注入
// 1. 创建中间件
php artisan make:middleware ThrottleRequests
php artisan make:middleware LogRequest
// 2. 中间件实现
class LogRequest
{
public function handle($request, Closure $next)
{
// 前置操作
Log::info('Request started', ['url' => $request->url()]);
$response = $next($request);
// 后置操作
Log::info('Request completed', ['status' => $response->status()]);
return $response;
}
}
class ThrottleRequests
{
public function handle($request, Closure $next)
{
if (Redis::get("throttle:{$request->ip()}") > 100) {
abort(429, 'Too Many Requests');
}
return $next($request);
}
}
// 3. 注册中间件(最佳方式:分组注册)
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
MiddlewareGroup::class, // 自定义
],
'api' => [
'throttle:60,1', // 使用参数
ThrottleRequests::class,
LogRequest::class,
],
];
手动实现中间件(不依赖框架)
<?php
interface MiddlewareInterface
{
public function handle(Request $request, callable $next): Response;
}
class MiddlewarePipeline
{
private array $middlewares = [];
public function add(MiddlewareInterface $middleware): self
{
$this->middlewares[] = $middleware;
return $this;
}
public function process(Request $request): Response
{
// 构建中间件链
$pipeline = array_reduce(
array_reverse($this->middlewares),
function ($next, MiddlewareInterface $middleware) {
return function ($request) use ($middleware, $next) {
return $middleware->handle($request, $next);
};
},
function ($request) {
return $this->handleRequest($request); // 最终处理器
}
);
return $pipeline($request);
}
}
// 使用示例
class AuthMiddleware implements MiddlewareInterface
{
public function handle(Request $request, callable $next): Response
{
if (!$request->hasHeader('Authorization')) {
return new Response('Unauthorized', 401);
}
return $next($request); // 传递给下一个中间件
}
}
class CorsMiddleware implements MiddlewareInterface
{
public function handle(Request $request, callable $next): Response
{
$response = $next($request);
$response->setHeader('Access-Control-Allow-Origin', '*');
return $response;
}
}
// 调用
$pipeline = new MiddlewarePipeline();
$pipeline->add(new AuthMiddleware());
$pipeline->add(new CorsMiddleware());
$response = $pipeline->process($request);
微服务中的中间件
// 使用 PhpMiddleware 库(独立)
use PhpMiddleware\Execution\MiddlewareRunner;
$middlewareStack = new MiddlewareRunner([
function ($request, $next) {
// 日志记录
Logger::info('Request', $request->toArray());
$response = $next($request);
Logger::info('Response', ['status' => $response->getStatusCode()]);
return $response;
},
function ($request, $next) {
// 缓存检查
if ($cached = Cache::get($request->getUri())) {
return new JsonResponse($cached);
}
return $next($request);
},
new RequestHandler() // 实际业务处理器
]);
$response = $middlewareStack->handle($request);
性能优化高级技巧
1 中间件缓存
class CacheableMiddleware
{
private static array $cache = [];
public function handle($request, Closure $next)
{
$key = $this->generateKey($request);
if (isset(self::$cache[$key])) {
return self::$cache[$key];
}
self::$cache[$key] = $next($request);
return self::$cache[$key];
}
private function generateKey($request): string
{
return md5($request->method() . ':' . $request->getRequestUri());
}
}
2 条件性中间件(避免不必要的处理)
class ConditionalMiddleware
{
public function handle($request, Closure $next)
{
// 只在特定条件下执行
if ($request->is('api/*')) {
// 只对API路由执行
}
if ($request->method() === 'GET') {
return $next($request); // GET请求跳过此中间件
}
return $next($request);
}
}
最佳实践总结
✅ 应该做的
- 单一职责原则:每个中间件只做一件事
// 错误示例 - 太多职责 class EverythingMiddleware { // 日志、认证、缓存... }
// 正确示例 class AuthMiddleware {} class LogMiddleware {} class CacheMiddleware {}
2. **使用中间件分组**:按功能域分组
```php
'api' => ['throttle', 'cors', 'auth:api']
'web' => ['csrf', 'session', 'cookies']
- 优先使用框架内置功能:避免重复造轮子
❌ 避免做的
- 在中间件中处理业务逻辑 - 应该放在控制器中
- 在中间件中进行数据库查询 - 除非是验证必须
- 中间件顺序混乱 - 考虑依赖关系
🚀 生产环境建议
// 1. 使用中间件优先级
protected $middlewarePriority = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\App\Http\Middleware\ValidatePostSize::class,
// 自定义中间件
];
// 2. 终端中间件(响应已生成后执行)
class TerminableMiddleware
{
public function terminate($request, $response)
{
// 日志记录、缓存预热等
// 此时响应已发送,适合后处理
}
}
选择合适的中间件策略取决于项目规模和需求,对于小型项目,使用框架内置的就够了;对于大型系统,考虑使用PSR-15中间件接口实现更好的解耦。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播