我有一个关于这里讨论的问题的后续问题: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
方法,因为在闭包内部工作允许使用更复杂的依赖关系实例化对象。
希望这能有所帮助。