您好,登錄后才能下訂單哦!
這篇文章主要介紹“PHP中的依賴注入容器是什么”,在日常操作中,相信很多人在PHP中的依賴注入容器是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PHP中的依賴注入容器是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
一個好的代碼結(jié)構(gòu)設計一定是松耦合的,這也是很多通用設計模式的宗旨,就是把分散在各處的同一個功能的代碼匯聚到一起,形成一個模塊,然后在不同模塊之間通過一些細小的、明確的渠道進行溝通。
在實踐中,不同功能和模塊之間的互相依賴是不可避免的,而如何處理好這些依賴之間的關(guān)系則是代碼結(jié)構(gòu)能否變得美好的關(guān)鍵。
< ?php class User { public function register($user) { // 注冊操作 ... // 發(fā)送確認郵件 $notify = new Notify(); $notify->sendEmail('register', $user);
}
}
class Notify
{
public function sendEmail($type, $data)
{
switch $type {
case 'register':
// 發(fā)送注冊確認郵件
$email = new Email($type);
$email->send($data);
...
}
}
}
class Email
{
public function send($data)
{
// 發(fā)送郵件
}
}
上述代碼中,三個類之間逐層依賴,三個類實例化的順序是 User -> Notify -> Email
也就是說我先實例化User類,可能執(zhí)行了一些代碼之后再去實例化我需要的其他類,比如Notify,以此類推。
這種依賴會讓我們不得不為了得到需要的依賴而去做的一些準備工作,有時候可能一個new操作還不夠。而這部分工作就是所說的耦合,他會讓一個獨立功能的類不得不去關(guān)心一些和自己的主體功能沒什么關(guān)系的操作。
解除一個類對其他類的依賴
要解決這個問題也很簡單,我可以先實例化好Email類,然后再實例化Notify,然后把Email對象作為參數(shù)傳給Notify,最后實例化User類,然后把Notify傳進去。這就是所謂的依賴注入,可以看到這個過程中類實例化的順序完全反過來了,先實例化被依賴的對象,而不是先實例化最終需要的對象,這是控制反轉(zhuǎn)。
代碼如下:
< ?php $email = new Email(); $notify = new Notify($email); $user = new User($notify);
可以通過構(gòu)造函數(shù)來注入需要的依賴,也可以用一些其他的方法。
用容器托管依賴
那又有新的問題,例子中只有三個類還好,那如果這個User類依賴Notify來發(fā)郵件,依賴Model來存數(shù)據(jù)庫,依賴redis來緩存,這樣固然把依賴關(guān)系轉(zhuǎn)移到了類的外部,但還是會導致我只想實例化一下User的時候,卻要手動做很多的準備工作,會讓代碼混亂。所以這個時候需要一個容器。而這個容器的作用就是替我來管理這些依賴。
< ?php // 容器 class Container implements ArrayAccess { protected $values = []; public function offsetGet($offset) { return $this->values[$offset]($this);
}
public function offsetSet($offset, $value)
{
$this->values[$offset] = $value;
}
}
在程序啟動的時候,我們可以在一個地方統(tǒng)一的注冊好一系列的基礎(chǔ)服務。
< ?php $container = new Container(); $container['notify'] = function($c) { return new Notify(); }; $container['email'] = function($c) { return new Email(); }; 就會變成這樣 PHP< ?php class User { public function register($user) { // 注冊操作 ... // 發(fā)送確認郵件 $container('notify')->sendEmail('register', $user);
}
}
class Notify
{
public function sendEmail($type, $data)
{
switch $type {
case 'register':
// 發(fā)送注冊確認郵件
$email = $container['email'];
$email->send($data);
...
}
}
}
class Email
{
public function send($data)
{
// 發(fā)送郵件
}
}
就是當User需要Notify的時候,會去向容器要這個類的對象,那至于Notify再依賴什么其他的東西,我就不用管了,因為Notify也會去向容器要它自己需要的依賴。所有這些依賴關(guān)系的處理就完全托管給容器了,我們既不需要去關(guān)心依賴之間的層次關(guān)系,也避免了依賴之間的耦合。
需要注意的是,依賴注入容器一般只接受一個匿名函數(shù),而不是一個實例化好的對象,匿名函數(shù)會告訴容器怎樣去獲得一個對象,這樣可以使得一個服務在被需要的時候才會去實例化。
到此,關(guān)于“PHP中的依賴注入容器是什么”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。