深入研究 Laravel 源码第四天

前言 单纯学习

分析 index.php http内核,将传入的请求发送到http内核或控制台内核,得到返回,终止请求

1、make(解析http控制台实例)
2、handle(处理请求)
3、Illuminate\Http\Request::capture()
4、send
5、terminate

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
//解析这个抽象的实例,在bootstrap/app.php中有注册单例App\Http\Kernel
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()//得到全局表单请求实例
);处理请求得到响应
$response->send();//发送响应
$kernel->terminate($request, $response)//终止请求

分析App\Http\Kernel 文件

namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
    忽略
}

分析Illuminate\Foundation\Http\Kernel

1. 引入

use Exception;//异常
use Throwable;//异常与错误
use Illuminate\Routing\Router;//路由类
use Illuminate\Routing\Pipeline;//路由管道类
use Illuminate\Support\Facades\Facade;//门面抽象类
use Illuminate\Contracts\Debug\ExceptionHandler;//异常处理程序
use Illuminate\Contracts\Foundation\Application;//基础应用接口
use Illuminate\Contracts\Http\Kernel as KernelContract;//基础http内核接口
use Symfony\Component\Debug\Exception\FatalThrowableError;

2. 成员变量

class Kernel implements KernelContract
{
    //应用实例
    protected $app 
    //路由实例
    protected $router; 
    // 应用程序的引导类
    protected $bootstrappers = [
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
    ];
    //中间件数组
    protected $middleware = [];
    //中间件组数组
    protected $middlewareGroups = [];
    //路由中间件
    protected $routeMiddleware = [];
    //*按优先级排序的中间件列表
    protected $middlewarePriority = [
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \Illuminate\Auth\Middleware\Authenticate::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class,
    ];

3 . 构造函数

    public function __construct(Application $app, Router $router)//依赖注入
    {
        $this->app = $app;   
        $this->router = $router;
        $router->middlewarePriority = $this->middlewarePriority;//按优先级排序的中间件列表
        foreach ($this->middlewareGroups as $key => $middleware) {
            $router->middlewareGroup($key, $middleware);//添加路由中间件组
        }
        foreach ($this->routeMiddleware as $key => $middleware) {
            $router->aliasMiddleware($key, $middleware);//添加中间件别名
        }
    }

4. 处理传入的HTTP请求

1、sendRequestThroughRouter

    public function handle($request)
    {
        try {
            //启用_method请求参数的支持,以确定预期的HTTP方法
            $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 Events\RequestHandled($request, $response)
        );

        return $response;
    }

5. 通过中间件/路由器发送给定的请求

1、bootstrap
2、Facade::clearResolvedInstance
3、send(设置通过管道发送的对象)
4、through(设置管道数组)
5、then(运行管道)
6、shouldSkipMiddleware
7、dispatchToRouter(获取路由调度器回调)

protected function sendRequestThroughRouter($request)
    {
        $this->app->instance('request', $request);//注册请求实例到request

        Facade::clearResolvedInstance('request');//清除已解析的门面实例

        $this->bootstrap();//运行引导程序

        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());//中间件中的$next参数
    }

6. 为HTTP请求引导应用程序

1、hasBeenBootstrapped
2、bootstrapWith
3、bootstrappers

 public function bootstrap()
    {
        //判断程序是否自举
        if (! $this->app->hasBeenBootstrapped()) {
            $this->app->bootstrapWith($this->bootstrappers());//运行给定的引导类数组
        }
    }

7. 返回路由调度器回调(中间件中的$next参数)

protected function dispatchToRouter()
    {
        return function ($request) {
            $this->app->instance('request', $request);

            return $this->router->dispatch($request);
        };
    }

8. 终止内核

1、terminateMiddleware
2、 $this->app->terminate()

 public function terminate($request, $response)
    {
        $this->terminateMiddleware($request, $response);//终止中间件
        $this->app->terminate();//终止应用
    }

9. 终止中间件

1、shouldSkipMiddleware
2、gatherRouteMiddleware
3、parseMiddleware
4、make

    protected function terminateMiddleware($request, $response)
    {
        //获取所有中间件
        $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
            $this->gatherRouteMiddleware($request),//获取当前请求的类的中间件
            $this->middleware//全局公共中间件
        );

        foreach ($middlewares as $middleware) {
            if (! is_string($middleware)) {
                continue;
            }
            [$name] = $this->parseMiddleware($middleware);
            $instance = $this->app->make($name);//解析中间件实例
            if (method_exists($instance, 'terminate')) {
                $instance->terminate($request, $response);//执行中间件终止方法
            }
        }
    }

10. gatherRouteMiddleware

protected function gatherRouteMiddleware($request)
    {
        if ($route = $request->route()) {
            return $this->router->gatherRouteMiddleware($route);//使用解析的类名收集给定路由的中间件
        }
        return [];
    }

11. 解析中间件

 protected function parseMiddleware($middleware)
    {
        [$name, $parameters] = array_pad(explode(':', $middleware, 2), 2, []);
        if (is_string($parameters)) {
            $parameters = explode(',', $parameters);
        }
        return [$name, $parameters];
    }

12. hasMiddleware(是否存在全局中间件)

public function hasMiddleware($middleware)
    {
        return in_array($middleware, $this->middleware);
    }

13. 插入新中间件到数组头部

public function prependMiddleware($middleware)
    {
        if (array_search($middleware, $this->middleware) === false) {
            array_unshift($this->middleware, $middleware);
        }
        return $this;
    }

14. 插入新中间件到数组尾部

public function pushMiddleware($middleware)
    {
        if (array_search($middleware, $this->middleware) === false) {
            $this->middleware[] = $middleware;
        }

        return $this;
    }

15. bootstrappers(获得应用引导程序)

protected function bootstrappers()
    {
        return $this->bootstrappers;
    }

16. 向异常处理程序报告异常

protected function reportException(Exception $e)
    {
        $this->app[ExceptionHandler::class]->report($e);
    }

17. 将异常输出到响应

protected function renderException($request, Exception $e)
    {
        return $this->app[ExceptionHandler::class]->render($request, $e);
    }

18. getMiddlewareGroups

public function getMiddlewareGroups()
    {
        return $this->middlewareGroups;
    }

19. getApplication

 public function getApplication()
    {
        return $this->app;
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!