2016-06-10 170 views
2

我想知道爲什麼Container::getInstance()可以返回一個應用程序類。爲什麼Container :: getInstance()返回一個應用程序類

例如:

我想打一個哈希海峽,我想知道他們是如何工作的:

app('hash')->make('password'); 

,我發現在laravel的源代碼:

供應商/ laravel /framework/src/Illuminate/Foundation/helpers.php

if (! function_exists('app')) { 
    /** 
    * Get the available container instance. 
    * 
    * @param string $make 
    * @param array $parameters 
    * @return mixed|\Illuminate\Foundation\Application 
    */ 
    function app($make = null, $parameters = []) 
    { 
     if (is_null($make)) { 
      return Container::getInstance(); 
     } 

     return Container::getInstance()->make($make, $parameters); 

    } 
} 

我不知道是什麼將返回,然後我dd(Container::getInstance()),我知道它可以返回一個應用程序類,但我不知道他們是如何工作的。

回答

0

也許我對我的回答有點遲,但無論如何。

說明是最新的Laravel框架版本5.3.24。

爲什麼調用app(),那然後調用Container::getInstance()返回對象,應用的實例? 例如,爲什麼

Route::get('/', function() { 
    var_dump(app()); 
}); 

輸出:

object(Illuminate\Foundation\Application) 
... 

因爲...在這裏,我們必須一步一步來,雖然它明白了一切。

  1. 用戶發起Web請求。該請求由/public/index.php
  2. /public/index.php處理包含以下內容:

    $app = require_once __DIR__.'/../bootstrap/app.php'; 
    
  3. /bootstrap/app.php具有以下線:

    $app = new Illuminate\Foundation\Application(
        realpath(__DIR__.'/../') 
    ); 
    
  4. 當$應用程序對象被實例化時,Illuminate\Foundation\Application類的構造是調用。

/vendor/laravel/framework/src/Illuminate/Foundation/Application.php

class Application extends Container implements ... 
    { 
     // ... 
     public function __construct($basePath = null) 
     { 
      // 5. constructor triggers the following method: 
      $this->registerBaseBindings(); 
      // ... 
     } 
     // ... 
     protected function registerBaseBindings() 
     { 
      // 6. which then triggers the following: 
      static::setInstance($this); 
      // 7. Important! $this points to class Application here 
      // and is passed to Container 
      // ... 
     } 
     // ... 
    } 
  • static::setInstance($this);指我們class Container,因爲class Application extends Container
  • /vendor/laravel/framework/src/Illuminate/Container/Container.php

    class Container implements ... 
        { 
         // ... 
         // 11. $instance now contains an object, 
         // which is an instance of Application class 
         protected static $instance; 
         // ... 
         public static function setInstance(ContainerContract $container = null) 
         { 
          // 9. $container = Application here, because it has been passed 
          // from class Application while calling static::setInstance($this); 
          // 10. Thus, static::$instance is set to Application here 
          return static::$instance = $container; 
         } 
         // ... 
        } 
    

    1. 現在,假設我們在我們的路由文件中寫入了以下行。 /routes/web.php

      Route::get('/', function() { 
          dd(app()); // 13. We a calling an app() helper function 
      }); 
      

    14調用的應用程序()使我們 /vendor/laravel/framework/src/Illuminate/Foundation/helpers.php

    // ... 
        /** @return mixed|\Illuminate\Foundation\Application */ 
        function app($make = null, $parameters = []) 
        { 
         // 15. $make is null, so this is the case 
         if (is_null($make)) { 
          // 16. The following static method is called: 
          return Container::getInstance(); 
         } 
         // ... 
        } 
        // ... 
    
  • 現在我們又回到了我們的容器類 /vendor/laravel/framework/src/Illuminate/Container/Container.php

    public static function getInstance() 
    { 
        // 18. Important! 
        // To this point static::$instance is NOT null, 
        // because it has already been set (up to "step 11"). 
        if (is_null(static::$instance)) { 
         static::$instance = new static; // Thus, we skip this. 
        } 
        // 19. static::$instance is returned 
        // that contains an object, 
        // which is an instance of Application class 
        return static::$instance; 
    } 
    
  • 步驟16-19的一些重要注意事項。

    重要注意事項1!

    Static Keyword

    聲明類屬性或方法爲靜態,使他們可以訪問 無需類的一個實例。

    重要注意事項2!

    static::$instance = new static;是不相關的調用我們的應用程序()函數在步驟13中,並在第一次對我來說有些誤導......

    但只是要注意,它利用Late Static Bindings

    0

    應用程序類(Illuminate \ Foundation \ Application)擴展了Container類。這是框架的核心,允許所有的依賴注入魔術,並且它遵循Sigleton模式,這意味着當您在代碼中的任何位置請求Application對象(使用app()輔助函數或更多內部Container::getInstance())時,您將獲得同樣的全局實例。

    沒有得到複雜:這使你可以綁定任何類成容器實例:

    app()->bind('MyModule', new MyModuleInstace()); 
    

    ,那麼你可以「解決」這個類從容器中有:

    app()->make('MyModule); 
    

    但請記住,有幾種方法可以做到這一點,具有不同的模式目標,這只是這個概念的基本演示。

    +1

    謝謝你的幫助,我不知道我得到了它,因爲我無法找到容器類將返回全局實例,甚至當它只有'app()',我知道make函數或實例綁定函數可以幫助我解決這個問題,但它只有'app()',no' - > make'或' - > bind',並且在'public /'中找到'$ app = new Illuminate \ Foundation \ Application;'' index.php',它們之間有什麼不同?它是一樣的嗎?但他們是不同的語法,謝謝 –

    相關問題