laravel核心:IOC容器
作用: 容器使得框架各個元件能很好的在一起工作。
在 《從百草園到三味書屋 (一)依賴注入》 中,我們定義了 BillerInterface和BillingNotifierInterface 介面。
//假設我們使用了Stripe來進行支付操作。我們可以將Stripe的支付實現繫結到容器裡,就像這樣
App::bind('BillerInterface', function()
{
return new StripeBiller(App::make('BillingNotifierInterface'));
});
//注意在我們處理BillingInterface時,我們額外需要一個BillingNotifierInterface的實現,也就是再來一個bind:
App::bind('BillingNotifierInterface', function()
{
return new EmailBillingNotifier;//可方便切換賬單通知介面的具體實現類
});
//一旦我們使用了容器,切換介面的實現就是一行程式碼的事兒。
class UserController extends BaseController{
public function __construct(BillerInterface $biller)
{
$this->biller = $biller;
}
}
//想在應用中只例項化某類一次?沒問題,使用singleton方法吧:
App::singleton('BillingNotifierInterface', function()
{
return new SmsBillingNotifier;
});
你的專案沒有使用Laravel?但你依然可以使用Laravel的IoC容器!只要用Composer安裝了illuminate/container包就可以了。
容器的核心:透過php反射類實現(php反射類,可以知道類的一切資訊)
//依靠這個強大的PHP特性, Laravel的IoC容器可以實現很有趣的功能!考慮接下來這個類
class UserController extends BaseController
{
public function __construct(StripBiller $biller)
{
$this->biller = $biller;
}
}
分析:
注意這個控制器的建構函式暗示著有一個StripBiller型別的引數。使用反射就可以檢測到這種型別暗示。當Laravel的容器無法解決一個型別的明顯繫結時,容器會試著使用反射來解決。程式流程類似於這樣的:
- 已經有一個StripBiller的繫結了麼?
- 沒繫結?那用反射來探測一下StripBiller吧。看看他都需要什麼依賴。
- 解決StripBiller需要的所有依賴(遞迴處理)
- 使用ReflectionClass->newInstanceArgs()來例項化StripBiller
class UserController extends BaseController
{
public function __construct(BillerInterface $biller)
{
$this->biller = $biller;
}
}
// 為何需要繫結介面例項
App::bind('BillerInterface','StripBiller');
分析:
假設我們沒有為BillerInterface做任何繫結, 容器該怎麼知道要注入什麼類呢?
要知道,interface不能被例項化,因為它只是個約定。如果我們不提供更多資訊的話,容器是無法例項化這個依賴的。
所以,我們需要明確指出哪個類要實現這個介面 App::bind('BillerInterface','StripBiller');
什麼是反射?
簡易反射連結:部落格:PHP 物件導向 (十一)反射類
本作品採用《CC 協議》,轉載必須註明作者和本文連結