laravel的服务器容器原理

interface Visit{
    public function go();

}

class Train implements Visit{
    public function go()
    {
        echo "go to Tibet by train";
    }

}

class Traveller{
    protected $trafficTool;
    public function __construct(Visit $trafficTool)
    {
        $this->trafficTool = $trafficTool;
    }

    public function visitTibet(){
        $this->trafficTool->go();
    }
}

class Container{

    public $bindings = [];
    public function bind($abstract, $concrete = null, $shared = false){

        if(!$concrete instanceof Closure){
            //如果不是回调函数,则产生默认的回调
            $concrete = $this->getClosure($abstract, $concrete);
        }
        //将回调函数注册到数组中
        $this->bindings[$abstract] = compact('concrete', 'shared');
    
    }

    //默认生成实例的回调函数
    public function getClosure($abstract, $concrete){
        //即build函数中的$concrete($this)。中实现调用
        return function ($c) use ($abstract, $concrete){
            $method = ($abstract == $concrete) ? 'build' : 'make';
            return $c->$method($concrete);
        };
    }

    //生成实例对象,首先要解决接口和要实例化类之间的依赖关系,通过make,指定生成注册树上的绑定的类
    public function make($abstract){

        $concrete = $this->getConcrete($abstract);//获取依赖

        if($this->isBuildable($concrete, $abstract)){

            $object = $this->build($concrete);
        }else{

            $object = $this->make($concrete);
        }

        return $object;
    }

    public function build($concrete){
        if($concrete instanceof Closure){
            return $concrete($this);//这个用法不是很清楚
        }

        //生成反射类
        $reflector = new ReflectionClass($concrete);
        //判断该类是否能实例化
        if (!$reflector->isInstantiable()){
            echo $message = '该类不能被实例化';
        }
        $constructor = $reflector->getConstructor();
        //如果没有依赖的类,那么就实例化自身
        if(is_null($constructor)){
            return new $concrete;
        }
        $dependencies = $constructor->getParameters();
        $instance = $this->getDependencies($dependencies);//获取依赖的对象
        return $reflector->newInstanceArgs($instance);//这里实现依赖注入
    }

//获取依赖的对象
    protected function getDependencies($parameters){
        $dependencies = [];
        foreach ($parameters as $parameter){
            $dependency = $parameter->getClass();//获取依赖的类名
            if(is_null($dependency)){
                $dependencies[] = null;
            }else{
                $dependencies[] = $this->resolveClass($parameter);
            }
        }
        return (array) $dependencies;
    }

    protected function resolveClass(ReflectionParameter $parameter){
        return $this->make($parameter->getClass()->name);
    }

    //获取绑定的回调函数
    public function getConcrete($abstract){
        if (!isset($this->bindings[$abstract])){
            echo '$abstract='.$abstract."</br>";
            return $abstract;
        }
        return $this->bindings[$abstract]['concrete'];
    }
    public function isBuildable($concrete, $abstract){
        return $concrete === $abstract || $concrete instanceof Closure;
    }

}

$app = new Container();
$app->bind('Visit','Train');//给Visit接口绑定具体的类
$app->bind('traveller', 'Traveller');
$tra = $app->make('traveller');
$tra->visitTibet();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值