zoukankan      html  css  js  c++  java
  • php--容器

    <?php
    class A{
        private $b;
        public function __construct(B $b){
            $this->b = $b;
        }
        public function dosomething(){
            $this->b->dosomething();
            echo __METHOD__, '我是a';
        }
    }
    
    class B{
        private $c;
        public function __construct(C $c){
            $this->c = $c;
        }
        public function dosomething(){
            $this->c->dosomething();
            echo __METHOD__, '我是b';
        }
    }
    
    class C{
        public function dosomething(){
            echo __METHOD__, '我是c';
        }
    }
    
    class Container
    {
        private $s = array();
        public function __set($k, $c){
            var_dump($k);
            $this->s[$k] = $c;
        }
    
        public function __get($k){
            var_dump($k);
            return $this->build($this->s[$k]);
        }
        public function build($className){
            // 判断是否是闭包函数
            if ($className instanceof Closure) {
                // 执行闭包函数,返回结果
                return $className($this);
            }
    
            // 反射
            $reflector = new ReflectionClass($className);
    
            // 检查类是否可以实例化,排除抽象类和接口
            if (!$reflector->isInstantiable()) {
                throw new Exception('cant isInstantiable this');
            }
    
            // 获取类的构造函数
            $constructor = $reflector->getConstructor();
    
            // 判断是否具有构造函数
            if (is_null($constructor)) {
                return new $className;
            }
    
            // 有构造函数的话,取构造函数的参数,通过reflectionParameter 数组返回参数列表
            $parameters = $constructor->getParameters();
    
            // 递归解析构造函数的参数
            $dependencies = $this->getDependencies($parameters);
    
            // 创建一个类的新实例,给出的参数将传递到类的构造函数
            return $reflector->newInstanceArgs($dependencies);
        }
    
        // 递归的解析构造函数的参数
        public function getDependencies($parameters){
            $dependencies = [];
            foreach ($parameters as $parameter) {
                $dependency = $parameter->getClass();
    
                if (is_null($dependency)) {
                    // 是变量,有默认值值设置默认值
                    $dependencies[] = $this->resolveNonClass($parameter);
                } else {
                    // 是一个类,递归解析
                    $dependencies[] = $this->build($dependency->name);
                }
            }
            return $dependencies;
        }
    
        // 返回默认值
        public function resolveNonClass($parameter){
            // 有默认值返回默认值
            if ($parameter->isDefaultValueAvailable()) {
                return $parameter->getDefaultValue();
            }
    
            throw new Exception('i have no idea what to do hear');
        }
    }
    
    // 使用容器,自动加载需要的类
    $class = new Container();
    $class->b = 'B';
    $class->a = function ($class){
        return new A($class->b);
    };
    $model = $class->a;
    $model->doSomething();

    注:上边的代码是借鉴的网上的资源,侵删,谢谢。理解过程是自己写的,不对的地方请大神批评

    /**
    * 解释一下上边示例的运行过程
    * 1,实例化容器对象
    * 2,给属性b进行赋值,触发了__set(),$s['b'] = 'B'
    * 3, 给属性a进行赋值,触发了__set(), $s['a'] = function(...)
    * 4, 获取属性a的值的时候触发了__get(), 然后调用方法build
    * 5, 判断出a的值为一个闭包函数,执行了该闭包函数
    * 6,执行过程中实例化a的时候,调用属性b,此时又触发了方法__get(), 调用build方法
    * 7,通过判断是否是闭包函数,是否是抽象类或者接口,然后通过反射,知道该类具有构造函数,通过反射得到其构造函数的参数,然后递归的解析构造函数的参数。在解析参数的过程中识别到了参数为一个类,因此递归的调用了build方法,接着经过一系列的判断,反射,解析等,创建了C类的新实例,然后将给出的参数传递到类的构造函数,然后实例化B类,实例化A类,再调用a的doSomething方法,触发b的doSomething,触发c的doSomething方法
    */

  • 相关阅读:
    XAML学习笔记之Layout(五)——ViewBox
    XAML学习笔记——Layout(三)
    XAML学习笔记——Layout(二)
    XAML学习笔记——Layout(一)
    从0开始搭建SQL Server 2012 AlwaysOn 第三篇(安装数据,配置AlwaysOn)
    从0开始搭建SQL Server 2012 AlwaysOn 第二篇(配置故障转移集群)
    从0开始搭建SQL Server 2012 AlwaysOn 第一篇(AD域与DNS)
    Sql Server 2012 事务复制遇到的问题及解决方式
    Sql Server 2008R2升级 Sql Server 2012 问题
    第一次ACM
  • 原文地址:https://www.cnblogs.com/rcltocode/p/10108381.html
Copyright © 2011-2022 走看看