Laravel思維導圖:快速學習Laravel之核心概念

Laravel

Posted by Laravel on 2019-10-13 09:00:00

Laravel 的核心概念包括:服務容器、服務提供者、門面(Facades)、契約(Contracts)。

服務容器是Laravel 的核心,是一個IoC 容器,是管理類依賴和運行依賴注入的有力工具。

服務提供者則提供服務並綁定服務至服務容器。是所有Laravel 應用程序引導啟動的中心所在。

Facades 為應用程序的服務容器中可用的類提供了一個「靜態」接口。它實際上是服務容器中那些底層類的「靜態代理」。

Laravel 的契約(Contracts )是一系列框架用來定義核心服務的接口。

不管是契約還是門面都可以創建出強大的、容易測試的Laravel 應用程序。

0x00 服務容器

Laravel 的核心就是一個IoC 容器,該容器提供了整個框架中需要的一系列服務。

IoC(Inversion Of Control)控制反轉,是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。IoC容器會根據類的依賴需求,自動在註冊、綁定的一堆實例中搜尋符合的依賴需求,並自動注入到構造函數參數中去。通過控制反轉,對像在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對像中。這就是依賴注入(Dependency Injection, DI)。依賴注入實質上是指:類的依賴通過構造器或在某些情況下通過「setter」方法進行「注入」。

如何實現與服務容器的綁定?

幾乎所有服務容器的綁定都是在服務提供者中進行的。在服務提供者內部,可以通過$this->app 來訪問容器的實例。

綁定的方式包括:

  • 簡單綁定

  • 綁定一個單例

  • 綁定實例

  • 綁定接口到實現

  • 情境綁定

  • 綁定包括原始數據在內的初始數據

  • 標記

其中,標記能夠針對某種類別的所有做綁定。

如何從服務容器解析出對象?

綁定後可以從服務容器中解析出對象才能夠使用。解析方法包括:

  • 通過make 方法,接收一個你想要解析的類或者接口

  • 通過數組方式從容器中解析對象

  • 自動注入

 

自動注入實例

下面的例子中,在控制器的構造函數中對應用程序定義的Repository 使用類型提示。這樣Repository 實例會被自動解析並註入到類中:

users = $users; 
    } 

    /** 
     *顯示指定ID的用戶信息。
     * 
     * @param int $id 
     * @return Response 
     */ 
    public function show($id) 
    { 
        //
    } 
}

0x01 服務提供者

Laravel 中,包括應用程序,以及所有的Laravel 核心服務,都是通過服務提供者引導啟動的。所謂的「引導啟動」指的是註冊事務,包括註冊服務容器綁定,事件監聽器,中間件,甚至路由。

所有服務提供者都需要繼承Illuminate\Support\ServiceProvider 類。大多數服務提供者都包含register 和boot 方法。register 方法中,只能將事務綁定到服務容器。不應該在register 方法中嘗試註冊任何事件監聽器,路由或者任何其他功能。可以為服務提供者的boot 方法設置類型提示。服務容器會自動注入需要的任何依賴。boot 方法將在所有其他服務提供者均已註冊之後調用。

所有服務提供者都在config/app.php 配置文件中註冊。可以選擇推遲服務提供者的註冊,直到真正需要註冊綁定時,這樣可以提供應用程序的性能。

0x02 門面(Facades)

Facades 工作原理

在Laravel 應用中,一個facade 就是一個提供訪問容器中對象的類。其中核心的部件就是Facade 類。不管是Laravel 自帶的Facades ,還是用戶自定義的Facades ,都繼承自Illuminate\Support\Facades\Facade 類。

Facade 基類使用__callStatic() 魔術方法在你的Facades 中延遲調用容器中對應對象的方法,在下面的例子中,調用了Laravel 的緩存系統。在代碼裡,我們可能認為是Cache 類中的靜態方法get 被調用了:

 $user]); 
    } 
}

注意在代碼的最上面,我們導入的是Cache facade 。這個facade 其實是我們獲取底層Illuminate\Contracts\Cache\Factory 接口實現的一個代理。我們通過這個facade 調用的任何方法,都會被傳遞到Laravel 緩存服務的底層實例中。

如果我們看一下Illuminate\Support\Facades\Cache 這個類,你會發現類中根本沒有get 這個靜態方法:

class Cache extends Facade 
{ 
    /** 
     *獲取組件在容器中註冊的名稱。
     * 
     * @return string 
     */ 
    protected static function getFacadeAccessor() { return 'cache'; } 
}

其實,Cache facade 是繼承了Facade 基類,並且定義了getFacadeAccessor() 方法。這個方法的作用是返回服務容器中對應名字的綁定內容。當用戶調用Cache facade 中的任何靜態方法時, Laravel 會解析到服務容器中綁定的鍵值為cache 實例對象,並調用這個對像對應的方法(在這個例子中就是get 方法)。

0x03 契約(Contracts)

如何使用契約?

Laravel 中的許多類型的類都是通過服務容器解析出來的。包括控制器、事件監聽器、中間件、任務隊列,甚至路由的閉包。所以說,要獲得一個契約的實現,你只需要解析在類的構造函數中相應的類型約束即可。

例如,看看這個事件監聽器,當事件監聽器被解析時,服務容器會從構造函數里讀取到類型約束,並註入對應的值。

redis = $redis; 
    } 

    /** 
     *處理事件。
     * 
     * @param OrderWasPlaced $event 
     * @return void 
     */
    public function handle(OrderWasPlaced $event) 
    { 
        // 
    } 
}