2013-04-02 139 views
4

我一直在挖掘Laravel的核心,因为我想了解它是如何工作的。但是我提出了一种方法,即使在3天后我也无法包裹我的头。 在start.php中,应用绑定到自己。到现在为止还挺好。但是当我检查$ app-> share方法时,我迷路了。Laravel核心方法混淆

public function share(Closure $closure) 
{ 
    return function($container) use ($closure) 
    { 

     // We'll simply declare a static variable within the Closures and if 
     // it has not been set we'll execute the given Closure to resolve 
     // the value and return it back to the consumers of the method. 
     static $object; 
     if (is_null($object)) 
     { 
      $object = $closure($container); 
     } 

     return $object; 
    }; 
} 

此方法返回一个匿名函数被执行时返回该应用的一个实例。我看到了吗?为什么是这样?为什么你想要返回一个闭包而不仅仅是实例。这似乎是一种奇怪的方式,但我确信有一个原因;)??

UPDATE 在start.php行:

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

所以我认为,$应用[ '应用']是一个封闭的对象。但是,如果我确实get_class,则该课程为Illuminate \ Foundation \ Application。 此外,也没有办法执行它,因为$ app'app'不会明显工作。

+0

这似乎是Singleton和控制反转(IoC)设计模式的组合。当然这是为了可扩展性,但我不确定为什么它完全像这样构建。 –

回答

3

$app没有正常的阵列,它实际上是Illuminate\Foundation\Application1一个实例,一个扩展的Illuminate\Container\Container2,它实现ArrayAccess。但你已经知道这一点,因为这是方法所在。

容器将键绑定到闭包,当访问键时,从内存中获取值,或者在第一次访问时调用绑定闭包并返回结果值。当容器上设置一个键时,它将被封闭在一个封闭物中,除非它已经是封闭物。

这为容器提供了一致的内部接口,以便代码不会经常键入检查其内容。它也只会将你实际使用的引用加载到内存中 - 认为闭包的占用空间比完全加载的类实例要小。但是一旦加载,您就可以获得与其他请求的相同实例一起工作的好处。

为什么应用程序未在容器上注册使用instance()虽然我不知道 - 也许它会在跟踪和转储输出中产生递归引用。

+0

非常感谢!真的很好的答案。当我读到它时,我意识到我与我的理论很接近,但你的回答显然更清晰了! – driechel