我会尽量简述:
所以,你已经知道 resolveFacadeInstance 方法是通过 Facade 类的 __callStatic 方法调用的,组件的 Facade (i.e. File extends Facade) 扩展了这个 Facade 类。
在框架的启动过程中,从public/index.php下面一行开始执行bootstrap/start.php文件
$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;
在这段代码 sn-p 中,require $framework.'/Illuminate/Foundation/start.php'; 行开始执行Foundation/start.php 文件,在这个文件中你可能会看到类似这样的内容
// ...
Facade::clearResolvedInstances();
// Notice this line
Facade::setFacadeApplication($app);
这行(如上所示)将application instanse 设置为Facade 类中的$app 属性
// 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();
在上面给出的这段代码sn-p中,框架注册的所有核心组件,正如你所知,每个组件都有一个服务提供者类(即FilesystemServiceProvider),每个服务提供者类都有一个方法@ 987654342@ 是(对于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; });
到$app['files'] 因此,当您调用File::get() 时,它最终会调用匿名函数,在这种情况下,是以下行
return static::$resolvedInstance[$name] = static::$app[$name];
调用static::$app['file'];的函数,该函数返回实例,但在返回之前,它将实例存储在$resolvedInstance变量中,因此,下次它可以从变量中返回实例,而无需再次调用匿名函数。
所以,看起来是这样的,static::$resolvedInstance[$name] = static::$app[$name]; 调用了返回实例的匿名函数,并且这个函数是在 app 通过启动过程启动时注册的。
重要:
Application 扩展 Container 和 Container 扩展 ArrayAccess 类,这就是为什么 $app 对象的属性可以使用数组表示法(访问)设置/获取。
我试图给你一个想法,但你必须一步一步地查看代码,你不会只读取/跟踪一次代码。