资讯专栏INFORMATION COLUMN

了解PHP容器(Container)的实现

warnerwu / 2559人阅读

摘要:看源代码了解的基本功能管理对象实例化到配置的过程对象本身不知道自己是由管理的,对一无所知。对象使用来管理依赖关系非常好,但不是必须的。

看 Laravel 源代码了解 Container

Dependency Injection Containers 的基本功能:

Container 管理对象实例化到配置的过程

对象本身不知道自己是由 Container 管理的,对 Container 一无所知。

这就是为什么 Container 能够管理任何 PHP 对象。 对象使用 DI 来管理依赖关系非常好,但不是必须的。

i
logger = $logger;
    }

    public function show() {
        $user = "小灰灰";
        $this->logger->execute($user);
    }
}

$useLogger = new UseLogger(new LogToFile());

$useLogger->show();
ii A
logger = $logger;
    }

    public function show() {
        $user = "小灰灰";
        $this->logger->execute($user);
    }
}
$useLogger = new UseLogger(new LogToFile());
 
$useLogger->show();
B
logger = $logger;
    }

    public function show() {
        $user = "小灰灰";
        $this->logger->execute($user);
    }
}
$useLogger = new UseLogger(new LogToDD());
 
$useLogger->show();
iii
logger = $logger;
    }

    public function show() {
        $user = "小灰灰";
        $this->logger->execute($user);
    }
}

$useLogger = new UseLogger(new LogToFile());
 
$useLogger->show();

echo "
"; $useLogger = new UseLogger(new LogToDD()); $useLogger->show();
终极版
logger = $logger;
    }

    public function show() {
        $user = "小灰灰";
        $this->logger->execute($user);
 
    }
}

class SimpleContainer {

    // 用于存储所有绑定 key-value
    protected static $container = [];

    public static function bind($name, Callable $resolver) {
        static::$container[$name] = $resolver;
    }

    public static function make($name) {
        if(isset(static::$container[$name])){
            $resolver = static::$container[$name] ;
            return $resolver();
        }
        throw new Exception("Binding does not exist in container");
    }
}

SimpleContainer::bind(Logger::class, function () {
    return new LogToDD();
});

$useLogger3 = new UseLogger(SimpleContainer::make(Logger::class));


$useLogger3->show();
示例
module = $module;
    }

    public function show(array $target){

        $this->module->activate($target);
    }
}

class PowerA implements SuperModuleInterface
{
    public function activate(array $target)
    {
        echo "
". __METHOD__;
        print_r(func_get_args());
    }
}

class PowerB implements SuperModuleInterface
{
    public function activate(array $target)
    {
        echo "
". __METHOD__;
        print_r(func_get_args());
    }
}



class Container
{
    protected $binds;

    protected $instances;

    /**
     * @param $abstract
     * @param $concrete
     * 把代词 绑定到容器里,为后续make
     */
    public function bind($abstract, $concrete)
    {
        if ($concrete instanceof Closure) {
            $this->binds[$abstract] = $concrete;
        } else {
            $this->instances[$abstract] = $concrete;
        }
    }

    /**
     * @param $abstract
     * @param array $parameters
     * @return mixed
     * 创建对象
     */
    public function make($abstract, $parameters = [])
    {
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }
        // 把容器对象$this,放到参数数组第一个元素。为call_user_func_array使用
        array_unshift($parameters, $this);
        
        // 这里$this->binds[$abstract] 绑定的闭包函数, 执行函数参数是$parameters
        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}


// 创建一个容器(后面称作超级工厂)
$container = new Container;


// 向该 超级工厂添加超能力模组的生产脚本
$container->bind("powerA", function($container) {
    return new PowerA;
});

// 同上
$container->bind("powerB", function($container) {
    return new PowerB;
});


// 向该 超级工厂添加超人的生产脚本
$container->bind("superman", function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});



echo "
";

// 开始启动生产
$superman_1 = $container->make("superman", ["powerA"]);
$superman_1->show(["a" => 1]);

$superman_2 = $container->make("superman", ["powerB"]);
$superman_2->show(["b" => 1]);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31720.html

相关文章

  • 从yii2框架中di容器源码中了解反射作用

    摘要:反射简介参考官方简介的话,具有完整的反射,添加了对类接口函数方法和扩展进行反向工程的能力。此外,反射提供了方法来取出函数类和方法中的文档注释。 反射简介 参考官方简介的话,PHP 5 具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。 YII2框架中示例 对于yii2框架,应该都知道di容器,...

    dantezhao 评论0 收藏0
  • 搞懂依赖注入, 用 PHP 手写简易 IOC 容器

    摘要:依赖注入控制反转的一种具体实现方法。接下来,我们使用依赖注入实现控制反转,使依赖关系倒置依赖被动传入。从单元测试的角度看,依赖注入更方便和操作,方便了测试人员写出质量更高的测试代码。 前言 好的设计会提高程序的可复用性和可维护性,也间接的提高了开发人员的生产力。今天,我们就来说一下在很多框架中都使用的依赖注入。 一些概念 要搞清楚什么是依赖注入如何依赖注入,首先我们要明确一些概念。 D...

    antz 评论0 收藏0
  • 团队一致性PHP开发环境之Docker

    摘要:环境模型简介是一个开源的应用容器引擎让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的机器上,也可以实现虚拟化。 docker php环境模型 showImg(https://segmentfault.com/img/bVbfiCy?w=1661&h=871); docker 简介 Docker 是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包...

    xuxueli 评论0 收藏0
  • 团队一致性PHP开发环境之Docker

    摘要:环境模型简介是一个开源的应用容器引擎让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的机器上,也可以实现虚拟化。 docker php环境模型 showImg(https://segmentfault.com/img/bVbfiCy?w=1661&h=871); docker 简介 Docker 是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包...

    niuxiaowei111 评论0 收藏0
  • 团队一致性PHP开发环境之Docker

    摘要:环境模型简介是一个开源的应用容器引擎让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的机器上,也可以实现虚拟化。 docker php环境模型 showImg(https://segmentfault.com/img/bVbfiCy?w=1661&h=871); docker 简介 Docker 是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包...

    邹强 评论0 收藏0

发表评论

0条评论

warnerwu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<