我对这里讨论的问题有一个后续问题:Laravel core method confusion
我与driechel(上面提到的问题的作者)的情况相同,目前已经习惯了Laravel 4 FW并检查了核心。虽然给出了一个精确的答案,但我仍然不了解逻辑和幕后发生的事情。所以我非常感谢进一步的解释。我知道这可能是重复的,但由于我无法发表评论,我会用一个新问题给它一个镜头。希望这样好。
从本文开始,我一直在从另一个角度看这个问题:http://blog.joynag.net/2013/05/facades-in-laravel-4-and-static-methods-resolution/
在检查调用File:get()
时,我最终得到了Container类的share函数,该函数使用这个实际参数share(function() { return new Filesystem; }
调用。
我无法弄清楚的是使用$container
。特别是在关闭时的第二次出现:
$object = $closure($container);
你能再次澄清一下吗?为什么$container
在这里作为参数传递,实际包含在其中的是什么?据我所知,$closure
在那一点上持有并执行没有输入参数的function() { return new Filesystem; }
。
我搞不清楚了。现在研究这个和PHP匿名函数/闭包连续两天仍然无法弄明白。我既不理解$closure($container)
的语法,也不理解逻辑。
作为参考,这是share
method @ v4.0.5。
那么,这里发生了什么。我将在几个步骤中解释它。
正如您所指出的,这种方法是从服务提供商处调用的。所以,FilesystemServiceProvider
称这个方法看起来像这样:
$this->app['files'] = $this->app->share(function() { return new Filesystem; });
它将此share
方法的返回值赋给容器中的绑定。简而言之,该返回值将是在闭包中返回的新Filesystem
实例。
share
方法只是在IoC容器中定义单例的另一种方法。所有这些一开始可能有点令人生畏。基本上,Laravel本身就是一个IoC容器。所有类都绑定为容器上的实例。有时这些实例应该是每个调用的相同实例。
如果您在GitHub上查看上面的引用方法,您会注意到在闭包内部定义了一个静态变量。然后它检查该变量是否为null,如果是,则解析闭包(这是返回我们新的Filesystem
实例的闭包)。然后它只返回变量。
现在,下次使用File::get()
时,它不需要再次实例化Filesystem
类,因为它已经被实例化并存储在静态$object
变量中。所以它只是返回相同的对象给你。
所以!真的,你可以用这个替换$this->app['files']
线,它仍然可以工作。
$this->app->instance('files', new Filesystem);
99%的服务实际上使用share
方法,因为在闭包内部工作允许使用更复杂的依赖关系来实例化对象。
希望这可以帮助。