Laravel5.3 流程粗粒度分析之bootstrap

从laravel入口文件index里面外面不难定位到Illuminate\Foundation\Http\Kernel的handle方法,同样也不难发现handle方法的核心是

$response = $this->sendRequestThroughRouter($request);

继续跟踪这个方法

/**
     * Send the given request through the middleware / router.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    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();

 

/**
     * Bootstrap the application for HTTP requests.
     *
     * @return void
     */
    public function bootstrap() { if (! $this->app->hasBeenBootstrapped()) { $this->app->bootstrapWith($this->bootstrappers()); } }

 

 

 

首先,我们先确定这个方法中的$this->app是类Illuminate\Foundation\Application以及$this->bootstrappers()如下所示数组

 

protected $bootstrappers = [
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        'Illuminate\Foundation\Bootstrap\RegisterProviders',
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

 

 

 

那么接下来我们查看$this->app->bootstrapWith($this->bootstrappers())

 

/**
     * Run the given array of bootstrap classes.
     *
     * @param  array  $bootstrappers
     * @return void
     */
    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]); } }

 

 

 

因为是粗粒度分析,我们同样只看这个方法的核心$this->make($bootstrapper)->bootstrap($this),$this->make($bootstrapper)这个我们简单的理解为new $bootstrapper即可,所以这句代码的意思就是将上面$bootstrappers数组里面的每个类实例化并调用他们的bootstrap方法,那么上面那些类都是干什么的呢,其实从类的名字也可以猜出大概的意思了。

 

Illuminate\Foundation\Bootstrap\DetectEnvironment::bootstrap,从名字看,像是检查环境,具体代码如下:

/**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) { if (! $app->configurationIsCached()) { $this->checkForSpecificEnvironmentFile($app); try {
          //$app->environmentPath()默认是我们的basePath,$app->environmentFile()默认是根目录里面的.env文件 (new Dotenv($app->environmentPath(), $app->environmentFile()))->load(); } catch (InvalidPathException $e) { // } } }

 

 

 Illuminate\Foundation\Bootstrap\LoadConfiguration::bootstrap从名字看,像是加载配置,代码如下

 

/**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) { $items = []; // First we will see if we have a cache configuration file. If we do, we'll load // the configuration items from that file so that it is very quick. Otherwise // we will need to spin through every configuration file and load them all. if (file_exists($cached = $app->getCachedConfigPath())) { $items = require $cached; $loadedFromCache = true; } $app->instance('config', $config = new Repository($items)); // Next we will spin through all of the configuration files in the configuration // directory and load each one into the repository. This will make all of the // options available to the developer for use in various parts of this app. if (! isset($loadedFromCache)) { $this->loadConfigurationFiles($app, $config); } $app->detectEnvironment(function () use ($config) { return $config->get('app.env', 'production'); }); date_default_timezone_set($config['app.timezone']); mb_internal_encoding('UTF-8'); }

 

 

 

 

Illuminate\Foundation\Bootstrap\ConfigureLogging::bootstrap从名字看,像是配置日志,代码如下

 

/**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) {
     //大概就是默认使用Monolog作为日志记录 $log = $this->registerLogger($app); // If a custom Monolog configurator has been registered for the application // we will call that, passing Monolog along. Otherwise, we will grab the // the configurations for the log system and use it for configuration. if ($app->hasMonologConfigurator()) { call_user_func( $app->getMonologConfigurator(), $log->getMonolog() ); } else { $this->configureHandlers($app, $log); } } /** * Register the logger instance in the container. * * @param \Illuminate\Contracts\Foundation\Application $app * @return \Illuminate\Log\Writer */ protected function registerLogger(Application $app) { $app->instance('log', $log = new Writer( new Monolog($app->environment()), $app['events']) ); return $log; }

 

 

 

 

Illuminate\Foundation\Bootstrap\HandleExceptions::bootstrap看名字,像是处理异常,代码如下

 /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) { $this->app = $app; error_reporting(-1); set_error_handler([$this, 'handleError']); set_exception_handler([$this, 'handleException']); register_shutdown_function([$this, 'handleShutdown']); if (! $app->environment('testing')) { ini_set('display_errors', 'Off'); } }

 

Illuminate\Foundation\Bootstrap\RegisterFacades::bootstrap看名字像是注册Facades,代码如下,config目录下app配置的aliases配置就是在这里加载的

 

/**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) { Facade::clearResolvedInstances(); Facade::setFacadeApplication($app); AliasLoader::getInstance($app->make('config')->get('app.aliases', []))->register(); }

 

 

 

 

Illuminate\Foundation\Bootstrap\RegisterProviders::bootstrap看名字像是注册Providers,代码如下,config目录下app配置的providers配置就是在这里注册的

/**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) { $app->registerConfiguredProviders(); }

 

Illuminate\Foundation\Bootstrap\BootProviders::bootstrap看名字像是启动Providers,代码如下,其实就是执行上面注册的Providers数组中各个Provide的boot方法

/**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app) { $app->boot(); }

 

/**
     * Boot the application's service providers.
     *
     * @return void
     */
    public function boot() { if ($this->booted) { return; } // Once the application has booted we will also fire some "booted" callbacks // for any listeners that need to do work after this initial booting gets // finished. This is useful when ordering the boot-up processes we run. $this->fireAppCallbacks($this->bootingCallbacks); array_walk($this->serviceProviders, function ($p) { $this->bootProvider($p); }); $this->booted = true; $this->fireAppCallbacks($this->bootedCallbacks); }

 

 

 

 

 

 

 

 

 

我们经常安装一个扩展功能的时候需要去config里面的app.php的providers和aliases里面添加一些东西,通过以上的大概流程分析,我们就知道laravel是怎么处理这些东西的。

 

转载于:https://www.cnblogs.com/hjyang2012/p/6277199.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值