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方法
    */

  • 相关阅读:
    JAVA FTP 客户端 .
    附件上传byte2hex二行制转字符串优化方法
    JSTL的c:forEach标签(${status.index})
    jco 连接池
    FOWARD和response.sendRedirect()区别
    Windows BAT命令编写大全
    SQLServer 触发器详解
    区分ff/ie6/ie7/ie8,解决样式不兼容
    android在学习——程序的退出
    关于struts2 获取页面表单信息的个人做法
  • 原文地址:https://www.cnblogs.com/rcltocode/p/10108381.html
Copyright © 2011-2022 走看看