<?php
class Container{
protected $instance;
protected $binds;
/**
* 绑定一个抽象类
* @param $abstract
* @param $concrete
*/
public function bind($abstract,$concrete){
if ($concrete instanceof Closure){
$this->binds[$abstract] = $concrete;
}else{
$this->instance[$abstract] = $concrete;
}
// var_dump($this);
echo "<br />";
}
/**
* 制造一个类
* @param $abstract
* @param array $parameter
* @return mixed
*/
public function make($abstract,$parameter = []){
if (isset($this->instance[$abstract])){ // 检测变量是否已设置并且非 NULL
return $this->instance[$abstract]; // 如果已经设置了则直接返回
}
echo "<pre>";
var_dump($parameter);
echo "</pre>";
echo "<br />";
echo "<br />";
echo "<br />";
echo "<br />";
array_unshift($parameter,$this); //在数组开头插入一个或多个单元 方便在下一步调用的时候 将之前需要实现的依赖,进行提前处理
echo "<pre>";
var_dump($parameter);
var_dump($this->binds[$abstract]);exit;
echo "</pre>";
return call_user_func_array($this->binds[$abstract],$parameter); //调用回调函数,并把一个数组参数作为回调函数的参数
}
}
// 创建一个容器(后面称作超级工厂)
$container = new Container;
// 向该 超级工厂 添加 超人 的生产脚本
$container->bind('superman', function($container, $moduleName) {
return new Superman($container->make($moduleName));
});
// 向该 超级工厂 添加 超能力模组 的生产脚本
$container->bind('xpower', function($container) {
return new XPower;
});
//var_dump(function($container) {
// return new XPower;
//});
$container->make("superman",['xpower']);
//首先在工厂的基础上增加一个容器 这个容器用来存储要实现的类 要是那些类当然先要告诉这个容器 也就是提前在容器中注册。
//通过bind数组的形式 将实现类的匿名函数以key (类名) value(实现方法)注册到容器中
//在注册的时候需要判断一下 如果是一个继承自匿名类则直接绑定 如果不是匿名类则使用 instances(模块) 变量 存储属性 用于实现一组依赖
//绑定成功后如果在使用到的地方在进行生产,彻底将模块和实现分离。
//在需要的时候就进行make,方法接收要是实现的类和模块参数,通过array_unshift调整call_user_func_array的参数顺序 将需要模块提前执行 最后执行在将模块注入到实现的类中