- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我研究了 Laravel 4 facades 的幕后情况。
我们以这个Facade为例:
File::get(someArgs);
如果我没记错的话,一步一步(过于简单化)的调用将是:
//static method invocation which are all extended from Facade class
File::__callStatic(get, someArgs)
//returns an instance of FileSystem
File::resolveFacedeInstance('files')
FileSystem->get(someArgs)
我感到困惑的是下面方法 File::resolveFacadeInstance() 的注释行:
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) return $name;
if (isset(static::$resolvedInstance[$name]))
{
return static::$resolvedInstance[$name];
}
/**
* The line that i'm confused about
*/
return static::$resolvedInstance[$name] = static::$app[$name];
}
我的问题是:
如果File::get()是被调用的Facade
static::$app[$name] 会解析为我认为 Application['files']或 Application->files 依次调用 Application->__get('files') 因为 Application 类中没有 files 属性。
如果只是这个方法的内容,如何返回FileSystem类?
public function __get($key)
{
return $this[$key];
}
最佳答案
我会尽量简短地描述:
因此,您已经知道 resolveFacadeInstance
方法是通过 Facade
类和组件的 Facade 的
扩展了这个 __callStatic
方法调用的(即 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;
在此代码片段中,require $framework.'/Illuminate/Foundation/start.php';
行开始执行 Foundation/start.php
文件并在这个文件你可能会看到这样的东西
// ...
Facade::clearResolvedInstances();
// Notice this line
Facade::setFacadeApplication($app);
此(上面给出的)行将 application
实例设置为 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();
在上面给出的代码片段中,框架注册的所有核心组件,如您所知,每个组件都有一个服务提供者类(即 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; });
$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
对象的属性。
我试图给你一个想法,但你必须一步一步地查看代码,你不会只阅读/跟踪代码一次就明白了。
关于php - 拉维尔 4 : How are Facades resolved?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20311336/
我正在使用 git clone 部署我的 Laravel 项目并使用 git pull 进行更新 它工作正常,但每次部署时,我都必须从 config/app.php providers 数组和 ali
我是一名优秀的程序员,十分优秀!