標籤:singleton function 標準 comment config doc str get body
PHP的高效IOC架構——CanoeDI
一個非常簡單且實用的IoC架構,相對於其他的Ioc架構有如下特點:
- 高效: 架構使用了非常實用且高效的演算法,使得架構本身對應用的影響微乎其微,且架構提供了C擴充,最大限度的將效能提升到最高。
- 配置簡單: 大多數情況下幾乎不需要額外的配置
- 自動裝配: 基於PHPDocument的property屬性來自動裝配
- 懶載入: 所有被注入的變數的執行個體都為即用即取, 不會產生記憶體垃圾
- IDE友好: 因為利用的是PHP的標準規範, 相容大部分IDE
安裝
編譯安裝,可以得到最大的效率:
| 123456 |
$ git clone https://github.com/dustinfog/canoe-di.git$ cd canoe-di/ext$ phpize$ ./configure$ make$ sudo make install |
而後編輯php.ini
| 12 |
[canoe-di]extension=canoe_di.so |
composer安裝 (生產環境如果已經編譯安裝了擴充,此步驟可省略。在開發環境,PHP源碼可以讓IDE提供程式碼完成提示,所以仍然推薦執行這一步):
| 1 |
composer require dustinfog/canoe-di |
使用擷取執行個體
| 12345 |
class ClassA{}//DI容器在處理類型時,會在第一次遇到的時候執行個體化,並且在以後使用中以單例的方式使用。$a = \Canoe\DI\Context::get(ClassA::class); |
基於標註的裝配
| 1234567891011121314151617181920212223 |
class ClassC{} use \Canoe\DI\DITrait;use \Canoe\DI\Context;/** * @property ClassC $c */class ClassA{ //需要引入一個trait,用以處理$c的擷取 use DITrait; public function test() { //這裡可以直接使用 print_r($this->c); }} $a = Context::get(ClassA::class);$a->test(); //試一下會發生什麼 |
@uses標註:
uses可以指定屬性使用的類或者容器裡的執行個體
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
interface InterfaceC { public function sayHello();} class ClassWorld implements InterfaceC{ public function sayHello() { echo "hello, world!\n"; }} class ClassC implements InterfaceC{ private $name; public function __construct($name) { $this->name = $name; } public function sayHello() { echo "hello, $name!\n"; }} use \Canoe\DI\DITrait;use \Canoe\DI\Context; /** * @property InterfaceC $c1 {@uses ClassWorld} //使用類名 * @property InterfaceC $c2 {@uses c2} //使用容器內的ID */class ClassA{ //需要引入一個trait,用以處理$c的擷取 use DITrait; public function test() { print_r($this->c1); print_r($this->c2); }} Context::set("c2", new ClassC("Bob"));// 更好的選擇:Context::registerDefinition("c2", function(){new ClassC("Bob")}) $a = Context::get(ClassA::class);$a->test(); //試一下會發生什麼 |
Singleton
有時候,我們需要在一個非DI環境裡有限的使用DI,這時候每個系統與DI容器的先借點都在調用Context::get()顯得很醜陋,架構裡提供了一個更加親民的調用方式:
| 123456789101112 |
use \Canoe\DI\SingletonTrait; class ClassA{ use SingletonTrait;} $a = ClassA::getInstance();// 與Context::get(ClassA::class)等價,但隱藏了Context調用。 $a = ClassA::getInstance("a1");// 與Context::get("a1")等價,但做了進一步的類型檢查,即a1取到的執行個體與ClassA必須有"is a"的關係。 |
預先定義
上面的例子都是在運行時來實現自動裝配的,但在某些時候可能需要手動預先建立一些定 義,以備後續使,架構提供了簡單的支援.
| 1234567891011 |
//註冊類Canoe\DI\Context::registerDefinition(‘a‘, ClassA::class);//註冊回調Canoe\DI\Context::registerDefinition( ‘b‘, function() { return new ClassB(); });//註冊執行個體Canoe\DI\Context::set(‘c‘, new ClassC()); |
配置
大多數時候,預先定義都是寫在設定檔裡,可以用下列的方法載入配置:
| 123456789 |
\Canoe\DI\Context::loadConfig([ ‘definitions‘ => [ //這裡是定義 ClassB::class, ], ‘beans‘ => [ //這裡可以預定義一些實際的值 ‘uid‘ => 5, ],]); |
轉寄 項目地址:https://github.com/dustinfog/canoe-di
PHP的高效IOC架構——CanoeDI