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
//通过服务器提供的变量创建一个HTTP请求实例
public static function capture()
{
static::enableHttpMethodParameterOverride();
return static::createFromBase(SymfonyRequest::createFromGlobals());
}
//创建一个请求实例通过Symfony实例
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;
}
处理请求
Illuminate\Foundation\Http\Kernel.php
//处理一个输入HTTP请求
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',
];
//将请求通过中间件和路由处理
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());
}
}
//针对请求为应用程序“拔靴带”
public function bootstrap()
{
if (! $this->app->hasBeenBootstrapped()) {
$this->app->bootstrapWith($this->bootstrappers());
}
}
Illuminate\Foundation\Application.php
//执行bootstrap类的数组
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
//创建一个别名加载的实例对象
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;
}
//在自动加载栈中注册一个自动加载函数
public function register()
{
if (!$this->registered) {
$this->prependToLoaderStack();
$this->registered = true;
}
}
//将这个加载函数加到自动加载栈的开始处
protected function prependToLoaderStack()
{
spl_autoload_register([$this, 'load'], true, true);
}
//加载一个类的别名
public function load($alias)
{
if (isset($this->aliases[$alias])) {
return class_alias($this->aliases[$alias], $alias);
}
}
Illuminate\Routing\Router类的实例,即通过“static::$app[$name]”实现,最终将会调用这个Router类实例中的get()方法。绕了一圈,终于绕出来了,现在明白注册外观的真正用途了吧,后面的如Request::input()等都是通过外观别名完成最终函数调用的。
对于别名Laravel框架中有两个,一个是容器核心别名,定义在Application类中,而存储在Application类实例的$aliases属性中(实际上该属性是在Container类中,因为Application类继承Container类,所以继承了这个属性,这里没有给出加上命名空间的全部名称);另一个是外观别名,定义在app.php配置文件中,程序运行后存储在AliasLoader类实例的$aliases属性中。
Illuminate\Support\Facades\Facade.php
服务提供者注册
Illuminate\Foundation\Bootstrap\RegisterProviders.php
//服务提供者注册
public function bootstrap(Application $app)
{
$app->registerConfiguredProviders();
}
Illuminate\Foundation\Application.php
//注册所有配置的服务提供者
public function registerConfiguredProviders()
{
$manifestPath = $this->getCachedServicesPath();
(new ProviderRepository($this, new Filesystem, $manifestPath))
->load($this->config['app.providers']);
}
when类是注册事件,只有当事件发生时才会自动注册这个服务提供者;
eager类会直接加载,加载方式和注册基础服务提供者的过程相同;
deferred类的服务提供者存储在列表中,需要加载时才会加载。
Illuminate\Foundation\ProviderRepository.php
//注册应用的服务提供者
public function load(array $providers)
{
//加载larave\bootstrap\cache\services.json文件中的服务提供者
$manifest = $this->loadManifest();
//加载服务清单, 这里包含程序所有的服务提供者并进行了分类
if ($this->shouldRecompile($manifest, $providers)) {
$manifest = $this->compileManifest($providers);
}
//服务提供者加载事件, 当这个事件发生时才自动加载这个服务提供者
foreach ($manifest['when'] as $provider => $events) {
$this->registerLoadEvents($provider, $events);
}
//提前注册那些必须加载的服务提供者, 以此为应用提供服务
foreach ($manifest['eager'] as $provider) {
$this->app->register($this->createProvider($provider));
}
//在列表中记录延迟加载的服务提供者, 需要时再加载
$this->app->setDeferredServices($manifest['deferred']);
}
启动服务
Illuminate\Foundation\Bootstrap\BootProviders.php
public function bootstrap(Application $app)
{
$app->boot();
}
Illuminate\Foundation\Application.php
//启动应用程序的服务提供者
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);
}
//启动给定的服务提供者
protected function bootProvider(ServiceProvider $provider)
{
if (method_exists($provider, 'boot')) {
return $this->call([$provider, 'boot']);
}
}