1. 程式人生 > 實用技巧 >IOC容器實現

IOC容器實現

interface MConfig
{
    public function getConfig();
}

class MysqlConfig implements MConfig
{
    public function getConfig()
    {
        // 獲取配置
        return ['host', 'name', 'pwd'];
    }
}

interface RConfig
{
    public function getConfig();
}

class RedisConfig implements RConfig
{
    public
function getConfig() { // 獲取配置 return ['host', 'name', 'pwd']; } } interface SMysql { public function query(); } class DbMysql implements SMysql { public $config; public function __construct(MConfig $config) { $this->config = $config->getConfig();
// do something } public function query() { echo __METHOD__ . PHP_EOL; } } interface SRedis { public function Set(); } class DbRedis implements SRedis { public function __construct(RConfig $config) { $this->config = $config->getConfig(); // do something
} public function set() { echo __METHOD__ . PHP_EOL; } } class Controller { public $mysql; public $redis; public function __construct(SMysql $mysql, SRedis $redis) { $this->mysql = $mysql; $this->redis = $redis; } public function action() { is_object($this->mysql) && $this->mysql->query(); is_object($this->redis) && $this->redis->set(); } } class Container { public $bindings = []; public function bind($key, $value) { if (!$value instanceof Closure) { $this->bindings[$key] = $this->getClosure($value); } else { $this->bindings[$key] = $value; } } public function getClosure($value) { return function () use ($value) { return $this->build($value); }; } public function make($key) { if (isset($this->bindings[$key])) { return $this->build($this->bindings[$key]); } return $this->build($key); } public function build($value) { if ($value instanceof Closure) { return $value(); } // 例項化反射類 $reflection = new ReflectionClass($value); // isInstantiable() 方法判斷類是否可以例項化 $isInstantiable = $reflection->isInstantiable(); if ($isInstantiable) { // getConstructor() 方法獲取類的建構函式,為NULL沒有建構函式 $constructor = $reflection->getConstructor(); if (is_null($constructor)) { // 沒有建構函式直接例項化物件返回 return new $value; } else { // 有建構函式 $params = $constructor->getParameters(); if (empty($params)) { // 建構函式沒有引數,直接例項化物件返回 return new $value; } else { $dependencies = []; // 建構函式有引數 foreach ($params as $param) { $dependency = $param->getClass(); if (is_null($dependency)) { // 建構函式引數不為class,返回NULL $dependencies[] = NULL; } else { // 類存在建立類例項 $dependencies[] = $this->make($param->getClass()->name); } } return $reflection->newInstanceArgs($dependencies); } } } return null; } } $app = new Container(); $app->bind('MConfig', 'MysqlConfig'); $app->bind('RConfig', 'RedisConfig'); $app->bind('SMysql', 'DbMysql'); $app->bind('SRedis', 'DbRedis'); $app->bind('controller', 'Controller'); $controller = $app->make('controller'); $controller->action();