其实中间件无非就相当于一个过滤器的东西,在框架中将 请求或者响应 进行一层层的过滤,实现这种功能最合适不过的就是责任链模式啦
责任链模式的实现可以看这篇随笔 【php设计模式】责任链模式
下面记录下在框架中如何实现中间件的
首先需要先定义一个中间件的抽象类,抽象类中应该包含该对象的下一级节点,以及设置节点的放法和处理请求的一个方法
<?php abstract class BaseMiddleware { protected $next_node = null; abstract public function handle(RequestInterface $request); final public function setNextMiddleware(BaseMiddleware $next) { $this->next_node = $next; } }
然后实现具体的中间件类
<?php class BeforeMiddleware extends BaseMiddleware { public function handle(RequestInterface $request) { var_dump("Before Middle"); if($this->next_node){ $this->next_node->handle($request); } } }
实现完这些我们还需要一个实例化每个中间件并且将它们依次执行类
<?php class MiddleHandle { private $middlewares = [ "appHttpMiddlewareBeforeMiddleware", "appHttpMiddlewareNextMiddleware", "appHttpMiddlewareAfterMiddleware" ]; private $first_obj; public function __construct() { $pre_obj = null; $next_obj = null; foreach ($this->middlewares as $v){ if(!$pre_obj){ $pre_obj = new $v; $this->first_obj = $pre_obj; }else{ $next_obj = new $v; $pre_obj->setNextMiddleware($next_obj); $pre_obj = $next_obj; } } } public function dispatch(RequestInterface $request) { $this->first_obj->handle($request); } }
这里我定义了三个中间件,运行效果如下
root@2e26c1b5178c:/home/www/wwwroot/MySwoole# php index.php string(13) "Before Middle" string(11) "Next Middle" string(12) "After Middle"