zoukankan      html  css  js  c++  java
  • Laravel 底层是如何处理HTTP请求

    一、概述

    web 服务器对 HTTP 请求的处理流程大体上都是这样的:在某个端口监听请求,请求进入后运行程序,然后将程序运行结果以响应的形式发送出去。

    Laravel 框架构建的 Web 应用处理 HTTP 请求的流程亦是如此。所有 HTTP 请求都会被转发到单入口文件 /public/index.php。

    二、剖析

    逐行分析 index.php 的代码。

    1、引入自动加载

    require __DIR__.'/../vendor/autoload.php';

    2、创建一个 Application 实例,作为全局的服务容器,并将处理请求的核心类Kernel实现实例 绑定到该容器中。

    $app = require_once __DIR__.'/../bootstrap/app.php';

    注:app.php文件内的处理:

    <?php
    // 创建一个 Application 实例
    $app = new IlluminateFoundationApplication(
        $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
    );
    
    // 绑定处理HTTP请求的接口实现 到服务容器
    $app->singleton(
        IlluminateContractsHttpKernel::class,
        AppHttpKernel::class
    );
    
    // 绑定处理CLI请求的接口实现 到服务容器
    $app->singleton(
        IlluminateContractsConsoleKernel::class,
        AppConsoleKernel::class
    );
    
    $app->singleton(
        IlluminateContractsDebugExceptionHandler::class,
        AppExceptionsHandler::class
    );
    
    // 返回应用程序实例
    return $app;

    3、从服务容器中解析处理 HTTP 请求的 Kernel 实例

    $kernel = $app->make(IlluminateContractsHttpKernel::class);

    这里的 make 方法在 IlluminateFoundationApplication 中,作用就是解析

    4、处理 HTTP 请求的核心代码

    $response = $kernel->handle(
        $request = IlluminateHttpRequest::capture()
    );

    $kernel 是 AppHttpKernel 的父类,即 IlluminateFoundationHttpKernel,我们进入到 handle() 方法

    /**
     * 处理传入的http请求,获取一个 Request,返回一个 Response
     * 输入http请求,返回http响应
     *
     * Handle an incoming HTTP request.
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();
            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            $this->reportException($e);
            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));
            $response = $this->renderException($request, $e);
        }
        $this->app['events']->dispatch(
            new RequestHandled($request, $response)
        );
        return $response;
    }

    我们发现实际进行处理的是 sendRequestThroughRouter() 这个方法

    protected function sendRequestThroughRouter($request)
    {
        $this->app->instance('request', $request);
        Facade::clearResolvedInstance('request');
    
        // 在发送请求到路由之前,先调用 bootstrap() 方法运用应用的启动类
        $this->bootstrap();
    
        /**
        * 以管道模式来处理 HTTP 请求
        *
        * 全局中间件都校验通过才会将请求分发到路由器进行处理
        * 路由器会将请求 URL 路径与应用注册的所有路由进行匹配,如果有匹配的路由,则先收集该路由所分配的所有路由中间件
        * 通过这些路由中间件对请求进行过滤,所有路由中间件校验通过才会运行对应的匿名函数或控制器方法,执行相应的请求处理逻辑
        * 最后准备好待发送给客户端的响应。
        */
        return (new Pipeline($this->app))
                ->send($request)
                ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                ->then($this->dispatchToRouter());
    }

    5、发送响应

    $response->send();

    6、终止程序,做一些善后清理工作(主要包括运行终止中间件,以及注册到服务容器的一些终止回调)

    $kernel->terminate($request, $response);

    链接:https://mp.weixin.qq.com/s/MJDo0MXPTN2fpfVzJZ42Og

     
  • 相关阅读:
    第四章——64位软件逆向技术-基本语法(上)
    第三章——静态分析技术-IDA的简单操作
    第二章——动态分析技术-OD常见问题
    工厂模式及其抽象工厂
    设计模式-原则
    设计模式-简单工厂模式
    设计模式-桥接模式
    设计模式
    Linux下安装软件心得
    光驱挂载和下载
  • 原文地址:https://www.cnblogs.com/clubs/p/14376239.html
Copyright © 2011-2022 走看看