Laravel學(xué)習(xí)教程之IOC容器的介紹與用例
前言
Laravel使用IoC(Inversion of Control,控制倒轉(zhuǎn),這是一個(gè)設(shè)計(jì)模式,可以先查看下百科)容器這個(gè)強(qiáng)有力的工具管理類依賴。依賴注入(也是一種設(shè)計(jì)模式,一般用于實(shí)現(xiàn)IoC)是一個(gè)不用編寫固定代碼來處理類之間依賴的方法,相反的,這些依賴是在運(yùn)行時(shí)注入的,這樣允許處理依賴時(shí)具有更大的靈活性。
理解 Laravel IoC容器是構(gòu)建強(qiáng)大應(yīng)用程序所必要的,也有助于Laravel 核心本身。下面話不多說了,來一起看看詳細(xì)的介紹吧。
基本用例
綁定一個(gè)類型到容器
IoC 容器有兩種方法來解決依賴關(guān)系:通過閉包回調(diào)或者自動解析。首先,我們來探究一下閉包回調(diào)。首先,需要綁定一個(gè)“類型”到容器中:
App::bind('foo', function($app)
{
return new FooBar;
});
從容器中取得一個(gè)類型
$value = App::make('foo');
當(dāng)執(zhí)行 App::make 方法,閉包函數(shù)被執(zhí)行并返回結(jié)果。
綁定一個(gè)”共享“類型到容器
有時(shí),你只想將綁定到容器的類型處理一次,然后接下來從容器中取得的都應(yīng)該是相同實(shí)例:
App::singleton('foo', function()
{
return new FooBar;
});
綁定一個(gè)已經(jīng)存在的類型實(shí)例到容器
你也可以使用instance方法,將一個(gè)已經(jīng)存在的對象接口綁定到容器中:
$foo = new Foo;
App::instance('foo', $foo);
哪里去注冊綁定呢
IoC綁定,很像事件句柄或者路由過濾,通常在"bootstrap code(引導(dǎo)代碼)"之后完成。換句話說,它們在你的應(yīng)用程序準(zhǔn)備處理請求,也即是在一個(gè)路由或者控制器被實(shí)際執(zhí)行之前執(zhí)行。和其他引導(dǎo)代碼一樣,start文件通常作為IoC綁定注冊一種方法。另外,你可以創(chuàng)建一個(gè)app/ioc.php(文件名不一定一樣)文件,并在start文件中包含它。
如果你的應(yīng)用程序有很大量IoC綁定,或者你想根據(jù)不同的分類將IoC綁定分割到不同的文件,你可以嘗試在服務(wù)提供器(見下面)中進(jìn)行綁定
自動解析
取得一個(gè)類
IoC容器足夠強(qiáng)大,在許多場景下不需要任何配置就能取得類。例如
class FooBar {
public function __construct(Baz $baz)
{
$this->baz = $baz;
}
}
$fooBar = App::make('FooBar');
注意:我們雖然沒有在容器中注冊FooBar類,容器仍然可以取得該類,甚至自動注入Baz依賴!
當(dāng)某個(gè)類型沒有綁定到容器,IoC容器將使用 PHP 的反射工具來檢查類和讀取構(gòu)造器的類型提示。使用這些信息,容器可以自動構(gòu)建類實(shí)例。
綁定一個(gè)接口實(shí)現(xiàn)
然而,在某些情況下,一個(gè)類可能依賴某個(gè)接口實(shí)現(xiàn),而不是一個(gè) “具體的類”。當(dāng)在這種情況下,App::bind方法必須通知容器注入哪個(gè)接口實(shí)現(xiàn):
App::bind('UserRepositoryInterface', 'DbUserRepository');
現(xiàn)在考慮下這個(gè)控制器:
class UserController extends BaseController {
public function __construct(UserRepositoryInterface $users)
{
$this->users = $users;
}
}
由于我們將 UserRepositoryInterface 綁定了具體類,DbUserRepository 在該控制器創(chuàng)建時(shí)將會被自動注入到該控制器。
實(shí)際用例
Laravel 提供了幾個(gè)方法使用 IoC 容器增強(qiáng)應(yīng)用程序可擴(kuò)展性和可測試性。一個(gè)主要的例子是取得控制器。所有控制器都通過 IoC 容器取得,意味著可以在控制器構(gòu)造方法中對依賴的類型提示,它們將自動被注入。
對控制器的依賴關(guān)系做類型提示
class OrderController extends BaseController {
public function __construct(OrderRepository $orders)
{
$this->orders = $orders;
}
public function getIndex()
{
$all = $this->orders->all();
return View::make('orders', compact('all'));
}
}
在這個(gè)例子中,OrderRepository 將會自動注入到控制器。意味著當(dāng) 單元測試 模擬請求時(shí),OrderRepository 將會綁定到容器以及注入到控制器中,允許無痛與數(shù)據(jù)庫層交互。
IoC 使用的其他例子
過濾器, composers, 和 事件句柄也能夠從IoC容器中獲取到。當(dāng)注冊它們的時(shí)候,只需要把它們使用的類名簡單給出即可:
Route::filter('foo', 'FooFilter');
View::composer('foo', 'FooComposer');
Event::listen('foo', 'FooHandler');
服務(wù)提供器
服務(wù)器提供器是將一組相關(guān) IoC 注冊到單一路徑的有效方法。將它們看做是一種引導(dǎo)組件的方法。在服務(wù)器提供器里,你可以注冊自定義的驗(yàn)證驅(qū)動器,使用 IoC 容器注冊應(yīng)用程序倉庫類,甚至是自定義 Artisan 命令。
事實(shí)上,大多數(shù)核心 Laravel 組件包含服務(wù)提供器。應(yīng)用程序所有注冊在服務(wù)提供器的均列在 app/config/app.php 配置文件的 providers 數(shù)組中。
定義服務(wù)提供器
要創(chuàng)建服務(wù)提供器,只需繼承 Illuminate\Support\ServiceProvider 類并且定義一個(gè) register 方法:
use Illuminate\Support\ServiceProvider;
class FooServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('foo', function()
{
return new Foo;
});
}
}
注意:在 register 方法,應(yīng)用程序通過 $this->app 屬性訪問 IoC 容器。一旦你已經(jīng)創(chuàng)建了提供器并且想將它注冊到應(yīng)用程序中, 只需簡單的放入 app 配置文件里 providers 數(shù)組中。
運(yùn)行時(shí)注冊服務(wù)提供器
你也可以使用 App::register 方法在運(yùn)行時(shí)注冊服務(wù)提供器:
App::register('FooServiceProvider');
容器事件
注冊獲取事件監(jiān)聽者
容器在每次獲取對象時(shí)都觸發(fā)一個(gè)事件。你可以通過使用 resolving 方法來監(jiān)聽該事件:
App::resolvingAny(function($object)
{
//
});
App::resolving('foo', function($foo)
{
//
});
注意:獲取到的對象將會傳入回調(diào)函數(shù)中。
譯者:mpandar(馬勝盼)
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
Yii2.0 RESTful API 基礎(chǔ)配置教程詳解
這篇文章主要介紹了Yii2.0 RESTful API 基礎(chǔ)配置教程,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
php中配置文件保存修改操作 如config.php文件的讀取修改等操作
有時(shí)候我們需要用php將一些配置參數(shù)寫到文件里面,方便后期讀取使用,這里就為大家分享一下具體的實(shí)現(xiàn)代碼,需要的朋友可以參考一下2021-05-05
利用PHP訪問數(shù)據(jù)庫_實(shí)現(xiàn)分頁功能與多條件查詢功能的示例
下面小編就為大家?guī)硪黄肞HP訪問數(shù)據(jù)庫_實(shí)現(xiàn)分頁功能與多條件查詢功能的示例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
php preg_match的匹配不同國家語言實(shí)例
這篇文章主要介紹了php preg_match的匹配不同國家語言實(shí)例的相關(guān)資料,需要的朋友可以參考下2016-12-12
基于php權(quán)限分配的實(shí)現(xiàn)代碼
本篇文章介紹了,基于php權(quán)限分配的實(shí)現(xiàn)代碼。需要的朋友參考下2013-04-04
實(shí)現(xiàn)WordPress主題側(cè)邊欄切換功能的PHP腳本詳解
這篇文章主要介紹了實(shí)現(xiàn)WordPress主題側(cè)邊欄切換功能的PHP腳本詳解,包括為WordPress主題添加管理選項(xiàng)的方法,需要的朋友可以參考下2015-12-12

