一個基於Laravel的應用,當WEB服務器接受到來自外部的請求後,會將這個這個請求解析到 應用根目錄的 public/index.php
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <[email protected]>
*/
/*
|--------------------------------------------------------------------------
| 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';
為Laravel應用引入了由Composer
提供的類加載器,這樣Laravel應用便無需再手動加載任 何的類。其加載原理不是此次探究的目標,所以僅僅這樣使用就好了。接下的代碼,便是重 點。
該類的繼承結構如下:
第三十五行代碼
1
$app = require_once __DIR__.'/../bootstrap/app.php';
它將我的視線引入到了另外一個文件中,去看看到底發生了什麼吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
<?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
是一個 Illuminate\Foundation\Application
對象,那麼在創 建這個對象的時候又發生了什麼呢?
從它的構造方法看起:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/**
* 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);
}
}
順著函數調用,往下看。在這個構造函數中,首先調用了registerBaseBindings
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
* 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);
}
這段代碼,是將實例對象注入到容器中。那麼,這個容器是什麼呢?答案還是要從這段調用 中去尋找。
static::setInstance($this)
所做的就是將 $this
賦值給自身的 instance
靜態變 量。重點看 $this->instance('app', $this)
。
instance
函數的作用是綁定一個已有對象到容器中,這個對象在容器中共享並且可以通 過鍵獲取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/**
* 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 是這樣的一個數組 ['actual key' => 'alias']
list($abstract, $alias) = $this->extractAlias($abstract);
// 實際上的行為是 $this->aliases[$alias] = $abstract;
$this->alias($abstract, $alias);
}
unset($this->aliases[$abstract]);
// 檢查是否有這個鍵是否已經注冊到容器中
// $bound 是一個boolean值
$bound = $this->bound($abstract);
$this->instances[$abstract] = $instance;
if ($bound) {
$this->rebound($abstract);
}
}
視線重新回到Application
類中,接下來調用了這個方法 $this->registerBaseServiceProviders()
,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
/**
* 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
的子類,它接受一個 Application
對象作為構造函數參數,存儲在實例變量 $app
中。
在 register
方法中,每個ServiceProvider被調用了自身的 register
方法。首先看 看 EventServiceProvider
中的吧。
1 2 3 4 5 6 7 8
public function register()
{
$this->app->singleton('events', function ($app) {
return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
return $app->make('Illuminate\Contracts\Queue\Factory');
});
});
}
上面方法體將一個 Illuminate\Events\Dispatcher
對象以鍵 events
綁定到了容器 中,它負責實現事件的調度。
再看看 Illuminate\Routing\RoutingServiceProvider
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public function register()
{
$this->registerRouter();
$this->registerUrlGenerator();
$this->registerRedirector();
$this->registerPsrRequest();
$this->registerPsrResponse();
$this->registerResponseFactory();
}
首頁是在Laravel中接觸的最多的 route
被注冊,它是 Illuminate\Routing\Router
對象。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
其他好文
http://www.cnblogs.com/wish123/p/4756669.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>