• LARAVEL IOC容器 示例解析


    <?php 
    
    class People
    {
        public $dog = null;
    
        public function __construct()
        {
            $this->dog = new Dog();
        }
    
        public function putDog(){
            return $this->dog->dogCall();
        }
    
    }
    
    
    
    class Dog{
        public function dogCall(){
            return 'go to home....';
        }
    }
    
    
    class Container
    {
    	/**
    	* 容器绑定,用来装提供的实例或者 提供实例的回调函数
    	* @var array
    	*/
    	public $building = [];
    
    	/**
    	 * 注册一个绑定到容器
    	 */
    	public function bind($abstract, $concrete = null, $shared = false)
    	{
    	    if(is_null($concrete)){
    	        $concrete = $abstract;
    	    }
    
    	    if(!$concrete instanceOf Closure){
    	        $concrete = $this->getClosure($abstract, $concrete);
    	        
    	    }
    
    	    $this->building[$abstract] =  compact("concrete", "shared");
    
    	    print_r($this->building);
    	    // $res = ($this->building)['Dog']['concrete'];
    	    // print_r($res);die;
    	    // var_dump($res instanceof Closure);die;
    
    	}
    
    	//注册一个共享的绑定 单例
    	public function singleton($abstract, $concrete, $shared = true){
    	    $this->bind($abstract, $concrete, $shared);
    	}
    
    
    
    
    	/**
    	 * 默认生成实例的回调闭包
    	 *
    	 * @param $abstract
    	 * @param $concrete
    	 * @return Closure
    	 */
    	public function getClosure($abstract, $concrete)
    	{
    	    return function($c) use($abstract, $concrete){
    
    	        $method = ($abstract == $concrete)? 'build' : 'make';
    
    	        print_r($method.PHP_EOL);
    
    	        return $c->$method($concrete);
    	    };
    	}
    
    
    
    
    
    	/**
    	 * 生成实例 
    	 */
    	public function make($abstract)
    	{
    	    $concrete = $this->getConcrete($abstract);
    
    	    $data = $this->isBuildable($concrete, $abstract);
    
    	    // print_r($concrete);die;
    
    	    if( $data ){
    
    	        $object = $this->build($concrete);
    
    	    }else{
    	        $object = $this->make($concrete);
    	    }
    
    
    
    	    return $object;
    	}
    
    
    
    
    
    	/**
    	 * 获取绑定的回调函数
    	 */
    	public function getConcrete($abstract)
    	{
    	    // if(! isset($this->building[$abstract])  ){
    	    //     return $abstract;
    	    // }
    
    	    if( is_object($abstract)  ){
    	        return $abstract;
    	    }
    
    
    	    return $this->building[$abstract]['concrete'];
    	}
    
    	/**
    	 * 判断 是否 可以创建服务实体
    	 */
    	public function isBuildable($concrete, $abstract)
    	{
    	    return $concrete === $abstract || $concrete instanceof Closure;
    	}
    
    
    
    
    	/**
    	 * 根据实例具体名称实例具体对象
    	 */
    	public function build($concrete)
    	{
    	    if($concrete instanceof Closure){
    
    	        return $concrete($this);
    	    }
    
    	    
    	    //创建反射对象
    	    $reflector = new ReflectionClass($concrete);
    
    
    	    print_r($reflector);
    
    	    if( ! $reflector->isInstantiable()){
    	        //抛出异常
    	        throw new Exception('error.');
    	    }
    
    	    $constructor = $reflector->getConstructor();
    
    	    print_r($constructor);
    	    if(is_null($constructor)){
    	        return new $concrete;
    	    }
    
    	    $dependencies = $constructor->getParameters();
    
    	    print_r($dependencies);
    
    
    	    $instance = $this->getDependencies($dependencies);
    
    	    print_r( $reflector->newInstanceArgs($instance) );
    
    	    return $reflector->newInstanceArgs($instance);
    
    	}
    
    
    	//通过反射解决参数依赖
    	public function getDependencies(array $dependencies)
    	{
    	    $results = [];
    	    foreach( $dependencies as $dependency ){
    	        $results[] = is_null($dependency->getClass())
    	            ?$this->resolvedNonClass($dependency)
    	            :$this->resolvedClass($dependency);
    	    }
    
    	    return $results;
    	}
    
    	//解决一个没有类型提示依赖
    	public function resolvedNonClass(ReflectionParameter $parameter)
    	{
    	    if($parameter->isDefaultValueAvailable()){
    	        return $parameter->getDefaultValue();
    	    }
    	    throw new Exception('error_one.');
    
    	}
    
    	//通过容器解决依赖
    	public function resolvedClass(ReflectionParameter $parameter)
    	{
    	    return $this->make($parameter->getClass()->name);
    
    	}
    
    }
    
    $app = new Container();
    
    
    $app->bind('Dog','Dog');
    $app->bind('People', 'People');
    $people = $app->make('People');
    echo $people->putDog();
    
    
    
    ?>
    
  • 相关阅读:
    【杭电】[2016]数据的交换输出
    【杭电】[2015]偶数求和
    【杭电】[2015]偶数求和
    【杭电】[2026]首字母变大写
    【杭电】[2026]首字母变大写
    【杭电】[2075]A|B?
    【杭电】[2075]A|B?
    【杭电】[2043]密码
    【杭电】[2043]密码
    SQL 06: 内连接 (多表查询)
  • 原文地址:https://www.cnblogs.com/handongyu/p/8888992.html
Copyright © 2020-2023  润新知