• lumen容器模仿


    <?php
    class Container {
    
    	private $bindings = [];
    	private $instances = [];
    
    	public function getClosure($concrete) {
    		return function($parameter = []) use($concrete) {
    
    			# 在这里我们找到了判断初始化函数的契机,利用反射我们可以做很多事,包括我们的问题
    			# 1.获得一个$concrete类反射
    			$reflector = new ReflectionClass($concrete);
    			# 2.判断这个类能否被实例化,例如 private function __construct(){}
    			if(!$reflector->isInstantiable()) {
    				throw new Exception("{$concrete} 无法被实例化");
    			}
    
    			# 3.获取构造函数反射方法
    			$constructor = $reflector->getConstructor();
    
    			# 4.获取参数列表
    			$parameters = $constructor->getParameters();
    
    			# 5.遍历参数列表
    			$instancesParams = [];
    			foreach ($parameters as $_parameter) {
    				# 如果已经$parameter中已经设置了对应的参数
    				if(isset($parameter[$_parameter->name])) {
    					$instancesParams[] = $parameter[$_parameter->name];
    					continue;
    				}
    
    
    				# 如果没设置判断一下这个参数是否存在默认值
    				if(!$_parameter->isDefaultValueAvailable()) {
    					throw new Exception("{$concrete} 无法被实例化,缺少参数{$_parameter->name}");
    				}
    
    				$instancesParams[] = $_parameter->getDefaultValue();
    			}
    
    			# 这里就需要通过反射来构建对象了
    //            return new $concrete($parameter);
    			return $reflector->newInstanceArgs($instancesParams);
    		};
    	}
    
    
    	public function bind($abstract , $concrete=null, $shared = false)
    	{
    		if (is_null($concrete)) {
    			$concrete = $abstract;
    		}
    
    		if (!$concrete instanceof Closure) {
    			$concrete = $this->getClosure($concrete);
    		}
    
    		$this->bindings[$abstract] = [
    			'concrete' => $concrete,
    			'shared' => $shared
    		];
    	}
    
    	public function make($abstract ,array $parameters = []) {
    		if (!isset($this->bindings[$abstract])) {
    			return false;
    		}
    
    		if (isset($this->instances[$abstract])) {
    			return $this->instances[$abstract];
    		}
    
    		# 先获取到具体的类型
    		$concrete = $this->bindings[$abstract]['concrete'];
    		# 这里需要思考一下
    		# 到目前为止我们的$this->bindings[$abstract]['concrete']里存储的都是通过getClosure方法生成的闭包。
    		# 那么直接在这里判断类型肯定行不通,所以我们跳到getClosure里面去看看
    		$object = $concrete($parameters);
    		if($this->bindings[$abstract]['shared']) {
    			$this->instances[$abstract] = $object;
    		}
    
    		return $object;
    	}
    }
    
    class Person{
    	private $name;
    	private $isProgrammer;
    	public function __construct($name,$isProgrammer = true) {
    		$this->name = $name;
    		$this->isProgrammer = $isProgrammer;
    	}
    
    	public function me() {
    		$message = $this->isProgrammer ? ',Ta是一个程序员' :'';
    		return "姓名: {$this->name} $message";
    	}
    }
    $container = new Container();
    $container->bind('Person',null,false);
    $p1 = $container->make('Person',[
    	'name' => 'lilei',
    	'age'=>10
    ]);
    
    $p2 = $container->make('Person',[
    	'name' => 'zhangsan',
    	'age'=>10
    ]);
    
    echo $p1->me();
    echo $p2->me();
    
    var_dump($p1,$p2);
    var_dump($p1 === $p2);
    

      

  • 相关阅读:
    Jackrabbit 中Session最佳实践
    Android 学习历程
    SmartFoxServer 学习笔记 002
    互联网的下一代
    VirtualBox 中 安装 Ubuntu Desktop 10 桌面分辨率的调整
    学习 SmartFoxServer 笔记 001
    手工转换中缀式与前、后缀式
    汉字传值奇数乱码问题解决策略
    git权限管理工具gitolite使用笔记(一)
    git 安装笔记
  • 原文地址:https://www.cnblogs.com/brady-wang/p/13734143.html
Copyright © 2020-2023  润新知