2013-04-02 145 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