【再讀lara】生命周期 ~ 請(qǐng)求實(shí)例化

public\index.php

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

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

Illuminate\Http\Request.php

//通過(guò)服務(wù)器提供的變量創(chuàng)建一個(gè)HTTP請(qǐng)求實(shí)例
public static function capture()
{
    static::enableHttpMethodParameterOverride();
    return static::createFromBase(SymfonyRequest::createFromGlobals());
} 
//創(chuàng)建一個(gè)請(qǐng)求實(shí)例通過(guò)Symfony實(shí)例
public static function createFromBase(SymfonyRequest $request)
{
    if ($request instanceof static) {
        return $request;
    }
    $content = $request->content;
    $request = (new static)->duplicate(
        $request->query->all(), $request->request->all(), $request->attributes->all(),
        $request->cookies->all(), $request->files->all(), $request->server->all()
    );
    $request->content = $content;
    $request->request = $request->getInputSource();

    return $request;
}

處理請(qǐng)求

Illuminate\Foundation\Http\Kernel.php

//處理一個(gè)輸入HTTP請(qǐng)求
public function handle($request)
{
    try {
        $request->enableHttpMethodParameterOverride();
        $response = $this->sendRequestThroughRouter($request);
} 
//省略異常處理部分代碼
$this->app['events']->fire('kernel.handled', [$request, $response]);
     return $response;
}


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',
    ];
//將請(qǐng)求通過(guò)中間件和路由處理
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());
}

}
//針對(duì)請(qǐng)求為應(yīng)用程序“拔靴帶”    
public function bootstrap()
{
    if (! $this->app->hasBeenBootstrapped()) {
        $this->app->bootstrapWith($this->bootstrappers());
    }
}

Illuminate\Foundation\Application.php

//執(zhí)行bootstrap類的數(shù)組
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]);
    }
}

Illuminate\Foundation\Bootstrap\RegisterFacades.php

 public function bootstrap(Application $app)
 {
        Facade::clearResolvedInstances();
        Facade::setFacadeApplication($app);
      AliasLoader::getInstance($app->make('config')->get('app.aliases'))->register();
}

Illuminate\Foundation\AliasLoader.php

//創(chuàng)建一個(gè)別名加載的實(shí)例對(duì)象
 public static function getInstance(array $aliases = [])
{
        if (is_null(static::$instance)) {
            return static::$instance = new static($aliases);
        }
        $aliases = array_merge(static::$instance->getAliases(), $aliases);
        static::$instance->setAliases($aliases);
        return static::$instance;
}


//在自動(dòng)加載棧中注冊(cè)一個(gè)自動(dòng)加載函數(shù)
public function register()
{
        if (!$this->registered) {
            $this->prependToLoaderStack();
            $this->registered = true;
        }
  }
  //將這個(gè)加載函數(shù)加到自動(dòng)加載棧的開(kāi)始處
  protected function prependToLoaderStack()
  {
        spl_autoload_register([$this, 'load'], true, true);
  }
  //加載一個(gè)類的別名  
  public function load($alias)
 {
        if (isset($this->aliases[$alias])) {
            return class_alias($this->aliases[$alias], $alias);
        }
}

Illuminate\Routing\Router類的實(shí)例,即通過(guò)“static::$app[$name]”實(shí)現(xiàn),最終將會(huì)調(diào)用這個(gè)Router類實(shí)例中的get()方法。繞了一圈,終于繞出來(lái)了,現(xiàn)在明白注冊(cè)外觀的真正用途了吧,后面的如Request::input()等都是通過(guò)外觀別名完成最終函數(shù)調(diào)用的。

對(duì)于別名Laravel框架中有兩個(gè),一個(gè)是容器核心別名,定義在Application類中,而存儲(chǔ)在Application類實(shí)例的$aliases屬性中(實(shí)際上該屬性是在Container類中,因?yàn)锳pplication類繼承Container類,所以繼承了這個(gè)屬性,這里沒(méi)有給出加上命名空間的全部名稱);另一個(gè)是外觀別名,定義在app.php配置文件中,程序運(yùn)行后存儲(chǔ)在AliasLoader類實(shí)例的$aliases屬性中。

Illuminate\Support\Facades\Facade.php

服務(wù)提供者注冊(cè)

Illuminate\Foundation\Bootstrap\RegisterProviders.php

//服務(wù)提供者注冊(cè)   
public function bootstrap(Application $app)
{
        $app->registerConfiguredProviders();
}

Illuminate\Foundation\Application.php

//注冊(cè)所有配置的服務(wù)提供者
 public function registerConfiguredProviders()
{
        $manifestPath = $this->getCachedServicesPath();
        (new ProviderRepository($this, new Filesystem, $manifestPath))
                    ->load($this->config['app.providers']);
}

when類是注冊(cè)事件,只有當(dāng)事件發(fā)生時(shí)才會(huì)自動(dòng)注冊(cè)這個(gè)服務(wù)提供者;
eager類會(huì)直接加載,加載方式和注冊(cè)基礎(chǔ)服務(wù)提供者的過(guò)程相同;
deferred類的服務(wù)提供者存儲(chǔ)在列表中,需要加載時(shí)才會(huì)加載。

Illuminate\Foundation\ProviderRepository.php

  //注冊(cè)應(yīng)用的服務(wù)提供者
  public function load(array $providers)
{
        //加載larave\bootstrap\cache\services.json文件中的服務(wù)提供者
   $manifest = $this->loadManifest();
        //加載服務(wù)清單, 這里包含程序所有的服務(wù)提供者并進(jìn)行了分類
        if ($this->shouldRecompile($manifest, $providers)) {
            $manifest = $this->compileManifest($providers);
        }

        //服務(wù)提供者加載事件, 當(dāng)這個(gè)事件發(fā)生時(shí)才自動(dòng)加載這個(gè)服務(wù)提供者
        foreach ($manifest['when'] as $provider => $events) {
            $this->registerLoadEvents($provider, $events);
        }
       //提前注冊(cè)那些必須加載的服務(wù)提供者, 以此為應(yīng)用提供服務(wù)
        foreach ($manifest['eager'] as $provider) {
            $this->app->register($this->createProvider($provider));
        }
        //在列表中記錄延遲加載的服務(wù)提供者, 需要時(shí)再加載
        $this->app->setDeferredServices($manifest['deferred']);
    }

啟動(dòng)服務(wù)

Illuminate\Foundation\Bootstrap\BootProviders.php

 public function bootstrap(Application $app)
{
        $app->boot();
}

Illuminate\Foundation\Application.php

//啟動(dòng)應(yīng)用程序的服務(wù)提供者  
public function boot()
{
        if ($this->booted) {
            return;
        }
        $this->fireAppCallbacks($this->bootingCallbacks);
        array_walk($this->serviceProviders, function ($p) {
            $this->bootProvider($p);
        });
        $this->booted = true;
        $this->fireAppCallbacks($this->bootedCallbacks);
 }

//啟動(dòng)給定的服務(wù)提供者
 protected function bootProvider(ServiceProvider $provider)
 {
        if (method_exists($provider, 'boot')) {
            return $this->call([$provider, 'boot']);
        }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容