gpt4 book ai didi

php - 拉维尔 4 : How are Facades resolved?

转载 作者:可可西里 更新时间:2023-10-31 22:41:39 27 4
gpt4 key购买 nike

我研究了 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::$app 如何在 Facade 类中初始化或赋值
  • 如果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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com