美文网首页PHP
(三)从零编写PHP容器-解决类重复依赖创建

(三)从零编写PHP容器-解决类重复依赖创建

作者: FinalZero | 来源:发表于2020-02-19 16:39 被阅读0次

    项目源码

    功能实现

    • 解决类重复依赖创建、解决相互依赖(A->B->A->B->...)、循环依赖(A->B->C->A->B->C->A->...)

    代码实现 Container

        /**
         * 解决相互依赖及循环依赖判断
         * @param string $abstract
         * @param array $tmp
         * @return Closure|object
         * @throws ReflectionException
         */
        public function createObjectNoEach(string $abstract, array $tmp = [])
        {
            if ($tmpInstance = &$tmp[$abstract]) {
                return $tmpInstance;
            }
            $refClass = new ReflectionClass($abstract);
            if ($refClass->getName() === Closure::class) {
                return function (){};
            } elseif ($refClass->hasMethod('__construct')) {
                $_constructParams = array_map(function (ReflectionParameter $param) use ($abstract, $tmp) {
                    if ($param->getClass()) {
                        if (array_key_exists($param->getClass()->getName(), $tmp)) {
                            throw new class('can not create a circular dependencies class object.') extends Exception implements ContainerExceptionInterface{ };
                        }
                        return $this->createObjectNoEach($param->getClass()->getName(), $tmp);
                    } elseif ($param->isDefaultValueAvailable()) {
                        return $param->getDefaultValue();
                    } elseif ($param->getType()) {
                        return [
                                'string' => '',
                                'int' => 0,
                                'array' => [],
                                'bool' => false,
                                'float' => 0.0,
                                'iterable' => [],
                                'callable' => function() {}
                            ][$param->getType()->getName()] ?? null;
                    } else {
                        return null;
                    }
                }, $refClass->getMethod('__construct')->getParameters());
            }
            return $tmpInstance = $refClass->newInstance(... ($_constructParams ?? []));
        }
    

    实现思路

    • 通过存储自动创建实例对象,在参数列表中出现相同的类时判断为循环并抛出异常

    添加代码

    1. 判断是否缓存有实例对象
    if ($tmpInstance = &$tmp[$abstract]) {
        return $tmpInstance;
    }
    
    1. 判断自动创建的类是否被创建过,如果被创建过则认为是递归,抛出异常
    if (array_key_exists($param->getClass()->getName(), $tmp)) {
        throw new class('can not create a circular dependencies class object.') extends Exception implements ContainerExceptionInterface{ };
    }
    return $this->createObjectNoEach($param->getClass()->getName(), $tmp);
    
    1. 存储自动创建的类实例
    return $tmpInstance = $refClass->newInstance(... ($_constructParams ?? []));
    

    示例

    相关文章

      网友评论

        本文标题:(三)从零编写PHP容器-解决类重复依赖创建

        本文链接:https://www.haomeiwen.com/subject/iebafhtx.html