请叫我阿武_Richer

不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂; ---共同学习; 积累学习!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

PHP 闭包实现

Posted on 2020-09-11 17:04  请叫我阿武_Richer  阅读(107)  评论(0)    收藏  举报

1. 研究laravel低层发现大量使用闭包:此位置做简单介绍

  

// ioc容器
class Ioc
{
    public $binding = [];

    public function bind($abstract, $concrete)
    {
        //此位置绑定仅为针对$abstract绑定一个(Closure 闭包)函数,
        // $ioc为闭包函数的形参;此位置传参在调用闭包函数时传入;
        // $concrete 为引入参数
        $this->binding[$abstract]['concrete'] = function ($ioc) use ($concrete) {
            return $ioc->build($concrete);
        };
    }

    public function make($abstract)
    {
        // 根据key获取binding的值; 此位置获取到的是闭包函数变量
        // 相当于 $concrete = function($ioc);
        $concrete = $this->binding[$abstract]['concrete'];
        // 给闭包函数$concrete 传入参数$this;
        return $concrete($this);
    }

    // 创建对象
    public function build($concrete) {
        $reflector = new \ReflectionClass($concrete);
        $constructor = $reflector->getConstructor();
        if(is_null($constructor)) {
            return $reflector->newInstance();
        }else {
            $dependencies = $constructor->getParameters();
            $instances = $this->getDependencies($dependencies);
            return $reflector->newInstanceArgs($instances);
        }
    }

    // 获取参数的依赖
    protected function getDependencies($paramters) {
        $dependencies = [];
        foreach ($paramters as $paramter) {
            $dependencies[] = $this->make($paramter->getClass()->name);
        }
        return $dependencies;
    }
}

//实例化IoC容器
$ioc = new Ioc();
$ioc->bind('user','User');
$user = $ioc->make('user');
$user->login();
public function bind($abstract, $concrete)
{
//此位置绑定仅为针对$abstract绑定一个(Closure 闭包)函数,
// $ioc为闭包函数的形参;此位置传参在调用闭包函数时传入;
// $concrete 为引入参数
$this->binding[$abstract]['concrete'] = function ($ioc) use ($concrete) {
return $ioc->build($concrete);
};
}

之前一直纠结 function($ioc)中; $ioc是怎么传入的;
下面做个介绍:
   $ioc 其实就是 闭包函数的参数;
   普通函数 function name($data){
      echo $data;  
   }
而闭包函数时没有函数名的;
   类似 $func = function($param) {}
   传参 $func($param)
  bind()方法只是给属性 $abstract 赋值 匿名函数