Laravel 加载之 bootstrap

未匹配的标注

简介

此章,主要讲的内容是 $this->bootstrap();Laravel 中的配置错误处理、配置日志记录、 检测应用环境 以及执行其他需要完成的任务 。

bootstrap 引导其实质是将下面的类中的 bootstrap 方法都执行一遍

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,
];

看一下 handle 方法

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 Events\RequestHandled($request, $response)
    );

    return $response;
}

代码中标注的重点的一行 $response = $this->sendRequestThroughRouter($request); 就是这个 handle 方法核心内容了。

我们继续看 sendRequestThroughRouter 方法

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

    Facade::clearResolvedInstance('request');

    $this->bootstrap();  // 这就是这一章要讲的东西了

    return (new Pipeline($this->app))
        ->send($request)
        ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
        ->then($this->dispatchToRouter());
}

代码中标注的 $this->bootstrap(); 就是 Laravel 引导配置加载的开始了,具体干了哪些工作呢:

  • 加载 .env 文件,将配置加载到内存中
  • 加载 config 目录下的所有配置文件
  • 修改系统默认异常处理函数(如语法错误等),将其替代为 Laravel 的异常处理。这就是为什么在开发 Laravel 应用时,语法出现错误,而报错信息已一种非常好看的界面显示的缘故
  • 注册 Facades ,将 Laravel 内的 Facades 类中的静态属性 $app 赋值为 服务容器
  • 注册服务提供者,区分即时实例化和延时实例化,即时的不需要标识别名,而延时的需要标识别名,主要对 config/app.phpproviders 键对应值(服务器提供者类全名)进行分类
  • 执行服务提供者的 boot 方法,其中路由文件加载和读取,就是在此步骤进行的

下面我们看一下 $this->bootstrap();

public function bootstrap()
{
    if (! $this->app->hasBeenBootstrapped()) {
        $this->app->bootstrapWith($this->bootstrappers());
    }
}

这段代码是指,有没有进行过引导呀,有的话,不进入引导程序,没有则进入

下面我们看一下进入引导的,先看 $this->bootstrappers()

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

这段就是返回了 bootstrappers 属性,它就是前言中展示的数组

下面我们看一下容器方法 bootstrapWith

public function bootstrapWith(array $bootstrappers)
{
    $this->hasBeenBootstrapped = true;

    foreach ($bootstrappers as $bootstrapper) {
        $this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);

        $this->make($bootstrapper)->bootstrap($this);  // 核心在这

        $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
    }
}

上面核心代码,就是遍历 $bootstrapper 数组,将里面的类实例化后,执行实例化后的 bootstrap 方法,将容器作为参数传入。

这一章,讲到这里,下一章我们看一下 $bootstrappers 数组的第一个值(类全名)的引导(即加载 .env

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,
];

本篇如有错误、不当或者需补充的内容,请各位同僚多提宝贵意见。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:1
讨论数量: 1
发起讨论 查看所有版本


AmberLavigne
$this->bootstrap(); 这个说的是哪里的?
0 个点赞 | 1 个回复 | 问答 | 课程版本 5.6