來源:http://yuez.me/laravel-yuan-ma-jie-du/?utm_source=tuicool&utm_medium=referral
目錄
入口文件 index.php
一個(gè)基于Laravel的應(yīng)用,當(dāng)WEB服務(wù)器接受到來自外部的請(qǐng)求后,會(huì)將這個(gè)這個(gè)請(qǐng)求解析到 應(yīng)用根目錄的 public/index.php
中。
Laravel源碼解讀-index.php (laravel_index.php)download
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 | <?php/** * Laravel - A PHP Framework For Web Artisans * * @package Laravel * @author Taylor Otwell <taylorotwell@Gmail.com> *//*|--------------------------------------------------------------------------| Register The Auto Loader|--------------------------------------------------------------------------|| Composer provides a convenient, automatically generated class loader for| our application. We just need to utilize it! We'll simply require it| into the script here so that we don't have to worry about manual| loading any of our classes later on. It feels nice to relax.|*/require __DIR__.'/../bootstrap/autoload.php';/*|--------------------------------------------------------------------------| Turn On The Lights|--------------------------------------------------------------------------|| We need to illuminate PHP development, so let us turn on the lights.| This bootstraps the framework and gets it ready for use, then it| will load up this application so that we can run it and send| the responses back to the browser and delight our users.|*/$app = require_once __DIR__.'/../bootstrap/app.php';/*|--------------------------------------------------------------------------| Run The Application|--------------------------------------------------------------------------|| Once we have the application, we can handle the incoming request| through the kernel, and send the associated response back to| the client's browser allowing them to enjoy the creative| and wonderful application we have prepared for them.|*/$kernel = $app->make(Illuminate/Contracts/Http/Kernel::class);$response = $kernel->handle( $request = Illuminate/Http/Request::capture());$response->send();$kernel->terminate($request, $response);
|
第二十一行代碼
1 | require __DIR__.'/../bootstrap/autoload.php';
|
為L(zhǎng)aravel應(yīng)用引入了由Composer
提供的類加載器,這樣Laravel應(yīng)用便無需再手動(dòng)加載任 何的類。其加載原理不是此次探究的目標(biāo),所以僅僅這樣使用就好了。接下的代碼,便是重 點(diǎn)。
Illuminate/Foundation/Application 類
該類的繼承結(jié)構(gòu)如下:

第三十五行代碼
1 | $app = require_once __DIR__.'/../bootstrap/app.php';
|
它將我的視線引入到了另外一個(gè)文件中,去看看到底發(fā)生了什么吧。
Laravel源碼解讀-app.php (laravel_app.php)download
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 | <?php/*|--------------------------------------------------------------------------| Create The Application|--------------------------------------------------------------------------|| The first thing we will do is create a new Laravel application instance| which serves as the "glue" for all the components of Laravel, and is| the IoC container for the system binding all of the various parts.|*/$app = new Illuminate/Foundation/Application( realpath(__DIR__.'/../'));/*|--------------------------------------------------------------------------| Bind Important Interfaces|--------------------------------------------------------------------------|| Next, we need to bind some important interfaces into the container so| we will be able to resolve them when needed. The kernels serve the| incoming requests to this application from both the web and CLI.|*/$app->singleton( Illuminate/Contracts/Http/Kernel::class, App/Http/Kernel::class);$app->singleton( Illuminate/Contracts/Console/Kernel::class, App/Console/Kernel::class);$app->singleton( Illuminate/Contracts/Debug/ExceptionHandler::class, App/Exceptions/Handler::class);/*|--------------------------------------------------------------------------| Return The Application|--------------------------------------------------------------------------|| This script returns the application instance. The instance is given to| the calling script so we can separate the building of the instances| from the actual running of the application and sending responses.|*/return $app;
|
看第十四行,原來$app
是一個(gè) Illuminate/Foundation/Application
對(duì)象,那么在創(chuàng) 建這個(gè)對(duì)象的時(shí)候又發(fā)生了什么呢?
從它的構(gòu)造方法看起:
Illuminate/Foundation/Application 構(gòu)造方法
123456789101112131415161718 | /** * Create a new Illuminate application instance. * * @param string|null $basePath * @return void */public function __construct($basePath = null){ $this->registerBaseBindings(); $this->registerBaseServiceProviders(); $this->registerCoreContainerAliases(); if ($basePath) { $this->setBasePath($basePath); }}
|
順著函數(shù)調(diào)用,往下看。在這個(gè)構(gòu)造函數(shù)中,首先調(diào)用了registerBaseBindings
方法。
Illuminate/Foundation/Application#registerBaseBindings
12345678910111213 | /** * Register the basic bindings into the container. * * @return void */protected function registerBaseBindings(){ static::setInstance($this); $this->instance('app', $this); $this->instance('Illuminate/Container/Container', $this);}
|
這段代碼,是將實(shí)例對(duì)象注入到容器中。那么,這個(gè)容器是什么呢?答案還是要從這段調(diào)用 中去尋找。
static::setInstance($this)
所做的就是將 $this
賦值給自身的 instance
靜態(tài)變 量。重點(diǎn)看 $this->instance('app', $this)
。
instance
函數(shù)的作用是綁定一個(gè)已有對(duì)象到容器中,這個(gè)對(duì)象在容器中共享并且可以通 過鍵獲取。
Illuminate/Container/Container#instance
1234567891011121314151617181920212223242526272829 | /** * Register an existing instance as shared in the container. * * @param string $abstract * @param mixed $instance * @return void */public function instance($abstract, $instance){ if (is_array($abstract)) { // $abstract 是這樣的一個(gè)數(shù)組 ['actual key' => 'alias'] list($abstract, $alias) = $this->extractAlias($abstract); // 實(shí)際上的行為是 $this->aliases[$alias] = $abstract; $this->alias($abstract, $alias); } unset($this->aliases[$abstract]); // 檢查是否有這個(gè)鍵是否已經(jīng)注冊(cè)到容器中 // $bound 是一個(gè)boolean值 $bound = $this->bound($abstract); $this->instances[$abstract] = $instance; if ($bound) { $this->rebound($abstract); }}
|
視線重新回到Application
類中,接下來調(diào)用了這個(gè)方法 $this->registerBaseServiceProviders()
,
Illuminate/Foundation/Application#registerBaseServiceProviders
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 | /** * Register all of the base service providers. * * @return void */protected function registerBaseServiceProviders(){ $this->register(new EventServiceProvider($this)); $this->register(new RoutingServiceProvider($this));}/** * Register a service provider with the application. * * @param /Illuminate/Support/ServiceProvider|string $provider * @param array $options * @param bool $force * @return /Illuminate/Support/ServiceProvider */public function register($provider, $options = [], $force = false){ if ($registered = $this->getProvider($provider) && !$force) { return $registered; } // If the given "provider" is a string, we will resolve it, passing in the // application instance automatically for the developer. This is simply // a more convenient way of specifying your service provider classes. if (is_string($provider)) { $provider = $this->resolveProviderClass($provider); } $provider->register(); // Once we have registered the service we will iterate through the options // and set each of them on the application so they will be available on // the actual loading of the service objects and for developer usage. foreach ($options as $key => $value) { $this[$key] = $value; } $this->markAsRegistered($provider); // If the application has already booted, we will call this boot method on // the provider class so it has an opportunity to do its boot logic and // will be ready for any usage by the developer's application logics. if ($this->booted) { $this->bootProvider($provider); } return $provider;}
|
其中,EventServiceProvider和RoutingServiceProvider分別是
Illuminate/Events/EventServiceProvider
Illuminate/Routing/RoutingServiceProvider
這些ServiceProvider是 Illuminate/Support/ServiceProvider
的子類,它接受一個(gè) Application
對(duì)象作為構(gòu)造函數(shù)參數(shù),存儲(chǔ)在實(shí)例變量 $app
中。
注入所有基礎(chǔ) Service Provider
在 register
方法中,每個(gè)ServiceProvider被調(diào)用了自身的 register
方法。首先看 看 EventServiceProvider
中的吧。
Illuminate/Events/EventServiceProvider#register
12345678 | public function register(){ $this->app->singleton('events', function ($app) { return (new Dispatcher($app))->setQueueResolver(function () use ($app) { return $app->make('Illuminate/Contracts/Queue/Factory'); }); });}
|
上面方法體將一個(gè) Illuminate/Events/Dispatcher
對(duì)象以鍵 events
綁定到了容器 中,它負(fù)責(zé)實(shí)現(xiàn)事件的調(diào)度。
再看看 Illuminate/Routing/RoutingServiceProvider
:
Illuminate/Routing/RoutingServiceProvider#register
1234567891011121314 | public function register(){ $this->registerRouter(); $this->registerUrlGenerator(); $this->registerRedirector(); $this->registerPsrRequest(); $this->registerPsrResponse(); $this->registerResponseFactory();}
|
首頁是在Laravel中接觸的最多的 route
被注冊(cè),它是 Illuminate/Routing/Router
對(duì)象。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
其他好文
http://www.companysz.com/wish123/p/4756669.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>