<?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);
手机扫一扫
移动阅读更方便
你可能感兴趣的文章