学习Slim Framework for PHP v3 (七)--route middleware怎么被add进来的?

  上两篇中分析了route是怎么被加进来的,以及如何被匹配的。这篇说一下route middleware是如何被加进来的,即add进来的。index.php的代码如下:

$app->get('/forbase', function ($request, $response, $args){
    Example\Module\Base::instance()->init($request,$response);
    return $response;
})->add(Example\MiddleWare\MyMiddleware::instance(Example\Module\Base::instance()));

  首先,确定的是$app->get()返回的是一个route类型变量,即接下来的add方法是属于route 的。

Route类的定义:

/**
 * Route
 */
class Route extends Routable implements RouteInterface
{
    use MiddlewareAwareTrait;

  继承了abstract Routable类,并实现了RouteInterface 接口。这个add方法是Routable抽象类的方法。

/**
     * Prepend middleware to the middleware collection
     *
     * @param mixed $callable The callback routine
     *
     * @return static
     */
    public function add($callable)
    {
        $callable = $this->resolveCallable($callable);
        if ($callable instanceof Closure) {
            $callable = $callable->bindTo($this->container);
        }

        $this->middleware[] = $callable;
        return $this;
    }

   将middleware加入了一个collection中了。在route被调用run的时候,就会将collection里的middleware都加入到middleware stack中。最后条用callMiddlewarestack()从栈顶执行到栈底。

/**
     * Run route
     *
     * This method traverses the middleware stack, including the route's callable
     * and captures the resultant HTTP response object. It then sends the response
     * back to the Application.
     *
     * @param ServerRequestInterface $request
     * @param ResponseInterface      $response
     *
     * @return ResponseInterface
     */
    public function run(ServerRequestInterface $request, ResponseInterface $response)
    {
        // Finalise route now that we are about to run it
        $this->finalize();

        // Traverse middleware stack and fetch updated response
        return $this->callMiddlewareStack($request, $response);
    }
 $this->finalize(); 实现了将collection 中的middleware都加入到 middlewarestack中。
/**
     * Finalize the route in preparation for dispatching
     */
    public function finalize()
    {
        if ($this->finalized) {
            return;
        }

        $groupMiddleware = [];
        foreach ($this->getGroups() as $group) {
            $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware);
        }

        $this->middleware = array_merge($this->middleware, $groupMiddleware);

        foreach ($this->getMiddleware() as $middleware) {
            $this->addMiddleware($middleware);
        }

        $this->finalized = true;
    }

  最后callMiddlewareStack的时候会被执行。

  从下一篇开始读读每一行代码,比这样走流程更细一些。只是,不知道我这样的方法是不是对的,和最效率的。求高人传授更好方法,先谢过。



  

 

posted @ 2016-01-28 18:26  浮萍生根  阅读(376)  评论(0编辑  收藏  举报