Laravel 4-容器类:共享函数&;闭包逻辑


Laravel 4 - Container class: share function & closure logic

我有一个关于这里讨论的问题的后续问题:Laravel核心方法混淆

我的处境和Drichel(上面问题的作者)以前一样,目前已经习惯了Laravel 4 FW并检查核心。虽然已经给出了确切的答案,但我仍然不明白其中的逻辑和幕后发生的事情。因此,我非常感谢你的进一步解释。我知道这可能是重复的,但由于我还不能发表评论,我会提出一个新的问题。希望这样可以。

从这篇文章开始,我一直从另一个角度来看待这一点:http://blog.joynag.net/2013/05/facades-in-laravel-4-and-static-methods-resolution/

当检查调用File:get()时,我最终到达Container类的共享函数,它是用这个实际参数share(function() { return new Filesystem; }调用的。

我只是不明白$container的用途。尤其是在闭包内的第二次出现时:

$object = $closure($container);

你能再澄清一下吗?为什么$container在这里作为参数传递,它实际上包含什么?据我所知,$closure此时保持并执行没有输入参数的function() { return new Filesystem; }

我迷路了。现在已经连续两天研究了这个和PHP匿名函数/闭包,但仍然无法弄清楚。我既不理解这里$closure($container)的语法,也不理解它的逻辑。

作为参考,这是share方法@v4.0.5。

那么,这里发生了什么。我将分几个步骤进行解释。

调用Share方法

正如您所指出的,此方法是从服务提供商调用的。因此,FilesystemServiceProvider调用这个方法,看起来像这样:

$this->app['files'] = $this->app->share(function() { return new Filesystem; });

它将此share方法的return值分配给容器中的绑定。简而言之,该返回值将是闭包中返回的新Filesystem实例。

那么共享做什么呢

share方法只是在IoC容器中定义单例的另一种方法。所有这些一开始可能有点吓人。基本上,Laravel本身就是一个IoC容器。所有类都作为实例绑定在容器上。有时,这些实例在每次调用中都应该是相同的实例。

如果你在GitHub上查看上面的引用方法,你会注意到在闭包内部定义了一个静态变量。然后,它检查该变量是否为null,如果为null,则解析闭包(这是返回新Filesystem实例的闭包)。然后它简单地返回变量。

现在,下次使用File::get()时,不需要再次实例化Filesystem类,因为它已经被实例化并存储在静态$object变量中。所以它只是将相同的对象返回给您。

所以真的,你可以用这个替换$this->app['files']行,它仍然可以工作。

$this->app->instance('files', new Filesystem);

99%的服务实际上使用share方法,因为在闭包内部工作允许使用更复杂的依赖关系实例化对象。

希望这能有所帮助。