它允许你将请求沿着处理者链进行传递。每个处理者都可以选择是否处理该请求以及是否将请求传递给下一个处理者。这种模式使得多个对象都有机会处理请求,从而避免了请求发送者和接收者之间的耦合。
首先,我们需要定义一个处理器接口,所有具体的处理器都将实现这个接口。
interface MiddlewareInterface { public function handle($request, callable $next); }
接下来,为每个处理步骤创建具体的处理器类。
class LogMiddleware implements MiddlewareInterface { private $logger; public function __construct(LoggerInterface $logger) { $this->logger = $logger; } public function handle($request, callable $next) { // 记录请求信息到日志 $this->logger->info("Request received: " . json_encode($request)); // 继续传递请求到下一个处理器 return $next($request); } }
class AuthMiddleware implements MiddlewareInterface { private $authService; public function __construct(AuthenticationService $authService) { $this->authService = $authService; } public function handle($request, callable $next) { if (!$this->authService->check($request)) { throw new AuthenticationException('Unauthorized'); } // 继续传递请求到下一个处理器 return $next($request); } }
class PermissionMiddleware implements MiddlewareInterface { private $permissionService; public function __construct(PermissionService $permissionService) { $this->permissionService = $permissionService; } public function handle($request, callable $next) { if (!$this->permissionService->hasPermission($request)) { throw new PermissionDeniedException('Permission denied'); } // 继续传递请求到下一个处理器 return $next($request); } }
最后,我们需要一种机制来链接这些处理器,并启动处理过程。这里我们使用一个简单的闭包链来模拟这一过程。
function middlewarePipeline(...$middlewares) { return function ($request) use ($middlewares) { $handler = function ($request) { return $request; }; // 默认处理器 foreach (array_reverse($middlewares) as $middleware) { $handler = function ($request) use ($middleware, &$handler) { return $middleware->handle($request, $handler); }; } return $handler($request); }; } // 创建中间件实例 $logMiddleware = new LogMiddleware($logger); $authMiddleware = new AuthMiddleware($authService); $permissionMiddleware = new PermissionMiddleware($permissionService); // 构建责任链 $pipeline = middlewarePipeline($logMiddleware, $authMiddleware, $permissionMiddleware); // 模拟 HTTP 请求 $request = ['method' => 'GET', 'path' => '/admin/dashboard']; try { // 执行责任链 $response = $pipeline($request); echo "Request processed successfully."; } catch (AuthenticationException | PermissionDeniedException $e) { echo $e->getMessage(); }
在这个例子中,我们展示了如何利用责任链模式来处理 HTTP 请求的不同阶段。这样做有几个好处:
解耦合:请求的发送者(客户端)不需要知道哪个处理器会最终处理请求,甚至不知道有多少个处理器参与其中。
灵活性:可以轻松地添加或移除处理器,而不会影响其他部分的代码。
复用性:每个处理器只负责特定的任务,因此可以在不同的场景下重复使用这些处理器。
清晰的责任分配:每个处理器专注于一个职责,这有助于提高代码的可读性和维护性。
通过责任链模式,您可以更优雅地管理应用程序中的请求处理流程,同时保持代码的简洁和模块化。这种模式非常适合于那些需要逐步处理请求或事件的应用场景。