Lumen源码分析之 一步一步带你实现Lumen容器(一)

https://www.jianshu.com/p/092f2e8fd580

<?php


class Container
{
    private $bindings = [];

    private $instances = [];

    public function getClosure($concrete)
    {
        return function($params = []) use($concrete) {
            $reflector = new ReflectionClass($concrete);

            if(!$reflector->isInstantiable()){
                throw new Exception("{$concrete} 无法被实例化");
            }

            $constructor = $reflector->getConstructor();

            $parameters = $constructor->getParameters();

            $instance = [];

            foreach($parameters as $_parameter){
                if(isset($params[$_parameter->name])){
                    $instance[] = $params[$_parameter->name];
                    continue;
                }

                if (!$_parameter->isDefaultValueAvailable()){
                    throw new Exception("{$concrete} 无法被实例化 缺少参数" );
                }

                $instance[] = $_parameter->getDefaultValue();
            }
            return $reflector->newInstanceArgs($instance);
        };
    }

    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 $params = [])
    {
        if(!isset($this->bindings[$abstract])){
            return false;
        }

        if(isset($this->instances[$abstract])){
            return $this->instances[$abstract];
        }

        $concrete = $this->bindings[$abstract]['concrete'];
        $object = $concrete($params);
        if($this->bindings[$abstract]['shared']){
            $this->instances[$abstract] = $object;
        }
        return $object;
    }
}



class Person{
    private $name;
    private $isProgrammer;
    public function __construct($name,$isProgrammer) {
        $this->name = $name;
        $this->isProgrammer = $isProgrammer;
    }

    public function me() {
        $message = $this->isProgrammer ? ',Ta是一个程序员' :'';
        return "姓名: {$this->name} $message";
    }
}
$container = new Container();
$container->bind('Person');
$p1 = $container->make('Person',[
    'isProgrammer'=>true,
    'name' => 'lilei',
]);

echo $p1->me();

  

原文地址:https://www.cnblogs.com/php-linux/p/12718160.html