1. 程式人生 > 實用技巧 >關於IoC容器的理解

關於IoC容器的理解

<?php
class Container{
    protected $instance; 
    protected $binds;

    /**
     * 繫結一個抽象類
     * @param $abstract
     * @param $concrete
     */

    public function bind($abstract,$concrete){

        if ($concrete instanceof Closure){
            $this->binds[$abstract] = $concrete;
        }else{
            $this->instance[$abstract] = $concrete;
        }
//        var_dump($this);
        echo "<br />";
    }

    /**
     * 製造一個類
     * @param $abstract
     * @param array $parameter
     * @return mixed
     */

    public function make($abstract,$parameter = []){
        if (isset($this->instance[$abstract])){ // 檢測變數是否已設定並且非 NULL
            return $this->instance[$abstract]; // 如果已經設定了則直接返回
        }
        echo "<pre>";
        var_dump($parameter);
        echo "</pre>";
        echo "<br />";
        echo "<br />";
        echo "<br />";
        echo "<br />";
        array_unshift($parameter,$this); //在陣列開頭插入一個或多個單元 方便在下一步呼叫的時候 將之前需要實現的依賴,進行提前處理
        echo "<pre>";
        var_dump($parameter);
        var_dump($this->binds[$abstract]);exit;
        echo "</pre>";

        return call_user_func_array($this->binds[$abstract],$parameter); //呼叫回撥函式,並把一個數組引數作為回撥函式的引數
    }
}

// 建立一個容器(後面稱作超級工廠)
$container = new Container;

// 向該 超級工廠 新增 超人 的生產指令碼
$container->bind('superman', function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});

// 向該 超級工廠 新增 超能力模組 的生產指令碼
$container->bind('xpower', function($container) {
    return new XPower;
});

//var_dump(function($container) {
//    return new XPower;
//});

$container->make("superman",['xpower']);

//首先在工廠的基礎上增加一個容器 這個容器用來儲存要實現的類 要是那些類當然先要告訴這個容器 也就是提前在容器中註冊。
//通過bind陣列的形式 將實現類的匿名函式以key (類名) value(實現方法)註冊到容器中
//在註冊的時候需要判斷一下 如果是一個繼承自匿名類則直接繫結 如果不是匿名類則使用 instances(模組) 變數 儲存屬性 用於實現一組依賴
//繫結成功後如果在使用到的地方在進行生產,徹底將模組和實現分離。
//在需要的時候就進行make,方法接收要是實現的類和模組引數,通過array_unshift調整call_user_func_array的引數順序 將需要模組提前執行 最後執行在將模組注入到實現的類中

參考 https://www.insp.top/learn-laravel-container