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']);
}
}