资讯专栏INFORMATION COLUMN

lumen5.5学习(三)

svtter / 3679人阅读

摘要:接着上篇分割线是的实例,但是文件中找不到方法在类内部看到,打开找到了方法,方法注释写的是主要用于运行应用以及发送响应主要看方法

接着上篇$app->run();
--------------------分割线------------------------

$app是Application的实例,但是Application.php文件中找不到run方法
在类内部看到use ConcernsRoutesRequests,打开找到了run方法,
run方法注释写的是主要用于运行应用以及发送响应

    /**
     * Run the application and send the response.
     *
     * @param  SymfonyRequest|null  $request
     * @return void
     */
    public function run($request = null)
    {
        $response = $this->dispatch($request);
        if ($response instanceof SymfonyResponse) {
            $response->send();
        } else {
            echo (string) $response;
        }

        if (count($this->middleware) > 0) {
            $this->callTerminableMiddleware($response);
        }
    }

主要看dispatch方法

    /**
     * Dispatch the incoming request.
     *
     * @param  SymfonyRequest|null  $request
     * @return Response
     */
    public function dispatch($request = null)
    {
        list($method, $pathInfo) = $this->parseIncomingRequest($request);
        try {
            return $this->sendThroughPipeline($this->middleware, function () use ($method, $pathInfo) {
                if (isset($this->router->getRoutes()[$method.$pathInfo])) {
                    return $this->handleFoundRoute([true, $this->router->getRoutes()[$method.$pathInfo]["action"], []]);
                }

                return $this->handleDispatcherResponse(
                    $this->createDispatcher()->dispatch($method, $pathInfo)
                );
            });
        } catch (Exception $e) {
            return $this->prepareResponse($this->sendExceptionToHandler($e));
        } catch (Throwable $e) {
            return $this->prepareResponse($this->sendExceptionToHandler($e));
        }
    }

因为请求的URL是 api.com/index.php/
$method.$pathInfo 打印出来是 array(1) { [0]=> string(4) "GET/" }
$this->router->getRoutes()是获取在web.php定义的所有路由,返回的是一个数组形式的数据:

array (size=3)
  "GET/" => 
    array (size=3)
      "method" => string "GET" (length=3)
      "uri" => string "/" (length=1)
      "action" => 
        array (size=1)
          0 => 
            object(Closure)[10]
              public "static" => 
                array (size=1)
                  "router" => 
                    object(LaravelLumenRoutingRouter)[6]
                      public "app" =>
                                ......

所以isset($this->router->getRoutes()[$method.$pathInfo]) 的结果就是 true
接着调用handleFoundRoute方法

    /**
     * Handle a route found by the dispatcher.
     *
     * @param  array  $routeInfo
     * @return mixed
     */
    protected function handleFoundRoute($routeInfo)
    {
        $this->currentRoute = $routeInfo;

        $this["request"]->setRouteResolver(function () {
            return $this->currentRoute;
        });

        $action = $routeInfo[1];

        // Pipe through route middleware...
        if (isset($action["middleware"])) {
            $middleware = $this->gatherMiddlewareClassNames($action["middleware"]);

            return $this->prepareResponse($this->sendThroughPipeline($middleware, function () {
                return $this->callActionOnArrayBasedRoute($this["request"]->route());
            }));
        }

        return $this->prepareResponse(
            $this->callActionOnArrayBasedRoute($routeInfo)
        );
    }
    

如果有配置中间件的话还会有中间件的处理(后面再写中间件的学习)
匹配到web.php里面的这个路由后
看到这段代码$this->callActionOnArrayBasedRoute($routeInfo)

    /**
     * Call the Closure on the array based route.
     *
     * @param  array  $routeInfo
     * @return mixed
     */
    protected function callActionOnArrayBasedRoute($routeInfo)
    {
        $action = $routeInfo[1];

        if (isset($action["uses"])) {
            return $this->prepareResponse($this->callControllerAction($routeInfo));
        }

        foreach ($action as $value) {
            if ($value instanceof Closure) {
                $closure = $value->bindTo(new RoutingClosure);
                break;
            }
        }

        try {
            return $this->prepareResponse($this->call($closure, $routeInfo[2]));
        } catch (HttpResponseException $e) {
            return $e->getResponse();
        }
    }

里面就是处理路由对应的响应方式,并且组装响应数据准备返回

定义的路由是

$router->get("/", function () use ($router) {
    return $router->app->version();
});

匹配到路由之后对应的处理是

function () use ($router) {
    return $router->app->version(); //"Lumen (5.5.2) (Laravel Components 5.5.*)"
}

所以$this->call($closure, $routeInfo[2])
得到的就是上一节的"Lumen (5.5.2) (Laravel Components 5.5.*)"
然后把处理后得到的数据传进$this->prepareResponse()方法中组装响应请求的数据
组装完毕后,回到最初的run方法接着往下$response->send()
追踪到SymfonyComponentHttpFoundationResponse这个类里面(组装响应数据也是这里面)

    /**
     * Sends content for the current web response.
     *
     * @return $this
     */
    public function sendContent()
    {
        echo $this->content;

        return $this;
    }

    /**
     * Sends HTTP headers and content.
     *
     * @return $this
     */
    public function send()
    {
        $this->sendHeaders();
        $this->sendContent();

        if (function_exists("fastcgi_finish_request")) {
            fastcgi_finish_request();
        } elseif ("cli" !== PHP_SAPI) {
            static::closeOutputBuffers(0, true);
        }

        return $this;
    }

从这里看出,那段"Lumen (5.5.2) (Laravel Components 5.5.*)"就是在这里echo出来的

到此为止,可以大概知道了框架从请求到响应的基本流程
其中还有一些中间件,事件监听等知识后续学习补上,有什么不对记得指出,互相学习~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26184.html

相关文章

  • lumen5.5学习(二)

    摘要:继续学习分割线看看是怎么输出这个数据目录下的加载了下的的自动加载加载的配置初始化应用初始化的内容指定项目基础目录注册服务容器注册异常处理实例 继续学习lumen5.5 -----------------------分割线----------------------- 看看是怎么输出Lumen (5.5.2) (Laravel Components 5.5.*)这个数据 public目录...

    shengguo 评论0 收藏0
  • lumen5.5学习(一)

    摘要:最近在学习框架写接口,记忆力比较差所以顺便写下笔记分割线因为直接学最新版的所以,记得开启的,,扩展还有可以用的打开命令 最近在学习lumen框架写API接口,记忆力比较差所以顺便写下笔记~ -----------------------------分割线-------------------------------- 因为直接学最新版的所以,PHP >=7.0记得开启php.ini的o...

    mindwind 评论0 收藏0
  • lumen5.5学习路由和中间件(四)

    摘要:想要做到这一点,你需要定义中间件为。如果你希望在及方法被调用时使用一致的中间件实例,只需在容器中使用容器的方法注册中间件以上就是路由和中间件的学习,最后那那其实理解得有点虚,有错记得指出修正,谢谢 前几篇了解完从请求到响应的流程后,仔细学习下路由和中间件的玩法 ----------------------------------分割线--------------------------...

    1fe1se 评论0 收藏0
  • windows下laravel5.5手写教程1(适合初学者)

    摘要:打开浏览器输入,如无意外,将出现如下图,表示框架安装成功。四系统内部后台管理系统这个是框架自带的后台登录管理系统,只需要简单的命令即可运行。出现上图即为,创建模型成功。 在PHP个各种web开发框架中,laravel算是一款简洁、优雅的开发框架,本人也刚刚接触到laravel,通过学习大神们的一些文章,下面是我的一些心得体会,希望可以给初学者一些帮助,大家一起进步。言归正传: 本人环境...

    GeekGhc 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<