我将尝试简短地描述一下:
所以,你已经知道了resolveFacadeInstance
方法通过调用__callStatic
的方法Facade
类和组件的 Facade(i.e. File extends Facade)
延伸这个Facade
class.
在框架的启动过程中,从public/index.php
下面一行开始执行bootstrap/start.php
file
$app = require_once __DIR__.'/../bootstrap/start.php';
所以,在这个(bootstrap/start.php
)文件中你可以看到一些代码,例如
// the first line, initiate the application
$app = new Illuminate\Foundation\Application;
// ...
// ...
// notice this line
require $framework.'/Illuminate/Foundation/start.php';
// ...
// last line
return $app;
在此代码片段中,require $framework.'/Illuminate/Foundation/start.php';
行开始执行Foundation/start.php
文件,在这个文件中你可能会看到类似这样的内容
// ...
Facade::clearResolvedInstances();
// Notice this line
Facade::setFacadeApplication($app);
这个(上面给出的)线集application
实例到$app
财产在Facade
class
// support/Facades/Facade.php
public static function setFacadeApplication($app)
{
static::$app = $app;
}
然后在Foundation/start.php
文件在底部,你可以看到类似这样的东西
/*
|--------------------------------------------------------------------------
| Register The Core Service Providers
|--------------------------------------------------------------------------
|
| The Illuminate core service providers register all of the core pieces
| of the Illuminate framework including session, caching, encryption
| and more. It's simply a convenient wrapper for the registration.
|
*/
$providers = $config['providers'];
$app->getProviderRepository()->load($app, $providers);
$app->boot();
在上面给出的代码片段中,框架注册了所有核心组件,并且如您所知,每个组件都有一个服务提供者类(即FilesystemServiceProvider
)并且在每个服务提供者类中都有一个方法register
这是(对于FilesystemServiceProvider
)
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app['files'] = $this->app->share(function() { return new Filesystem; });
}
那么,在这种情况下$this->app['files']
环境 (return new Filesystem
) 一个匿名函数,它返回filesystem
当被执行时
$this->app['files'] = $this->app->share(function() { return new Filesystem; });
to $app['files']
所以,当你打电话给File::get()
,它最终调用匿名函数,在本例中,以下行
return static::$resolvedInstance[$name] = static::$app[$name];
调用该函数static::$app['file'];
该函数返回实例,但在返回之前,它将实例存储在$resolvedInstance
变量,因此,下次它可以从变量返回实例,而无需再次调用匿名函数。
所以,看起来是这样的,static::$resolvedInstance[$name] = static::$app[$name];
调用返回实例的匿名函数,并且该函数是之前注册的,当app
通过启动过程启动。
重要的 :
Application
延伸Container
and Container
延伸数组访问 http://php.net/manual/en/class.arrayaccess.php类,这就是为什么,$app
可以使用数组表示法(访问)设置/获取对象。
我试图给你一个想法,但你必须一步一步地查看代码,你不会只阅读/跟踪代码一次。