php di容器,实现一个简单的di容器

之前看了好多框架,laravel,thinkphp,yii等等。基本上都使用了容器。对于我而言,虽然看懂了laravel是怎么写的,但是如果自己不去尝试一下,始终觉得不会这个东西。

下面的代码是我实现的一个简单的容器,很多地方处理并不是很好,但是应该已经足够了。

class Container{

//$binds 这个变量保存,是名字=>实例的映射

private $binds = [];

public static $instance = null;

/**

* 单例

*/

public static function getInstance(){

if(static::$instance == null){

static::$instance = new static();

return static::$instance ;

}

return static::$instance;

}

/**

* 一开始是受到laravel的影响,所以写了一个bind函数,

* 看完laravel的容器实现,印象之中,$concrete和$abstract来回变换。

* 下面的代码有点像thinkphp的里面的实现,好理解一点

*/

public static function bind($name,$class = null){

if($class instanceof Closure){

static::getInstance()->binds[$name] = $class;

}else if(is_object($class)){

static::getInstance()->binds[$name] = $class;

}else{

//在这里开始make一个数组,laravel好像是make和build分开的。

static::getInstance()->make($name);

}

}

/**

* 核心是make方法了

*/

public static function get($name){

return static::getInstance()->make($name);

}

/**

* 核心make方法

*/

public function make($name){

try{

//根据类名去查找$this->binds实例是否已经存在,如果存在就直接返回

if(array_key_exists($name,$this->binds)){

return $this->binds[$name];

}

//根据类名得到它的反射类

$reflectClass = new ReflectionClass($name);

//利用反射类

$constructor = $reflectClass->getConstructor();

//如果没有构造器的话,就直接去实例化它

$params = [];

if(!is_null($constructor)){

//获取构造器中的方法

$constructorParams = $constructor->getParameters();

// var_dump($constructorParams);

//保存构造器的参数

foreach($constructorParams as $constructorParam){

//这个地方主要是判断参数是否是类,如果是就递归的构造它,不是就简单的添加到$this->params中

if(!is_null($constructorParam->getType())){

$params[] =$this->make($constructorParam->name,$constructorParam->name);

}else{

$params[] = $constructorParam->name;

}

}

}

//在这个地方构造实例

$class = $reflectClass->newInstanceArgs($params);

//绑定

$this->binds[$name] = $class;

return $class;

}catch(ReflectionException $e){

echo $e->getMessage();

}

}

private function __construct(){}

private function __clone(){}

}

?>

下面是我的测试文件了,

require "./Container.php";

class TestFather{

private $name = "TestFather";

public function __construct(){

}

}

class Test extends TestFather{

private $name = "Test";

// public function __construct(DI $di, DI2 $di2,$name){

// }

public function __construct(DI $di,$name,$param_2 =[]){

}

public function sayName(){

echo $this->name;

}

public function sayDI2Name(DI2 $di2){

//如果这么写的,di2方法会先于前面的字符串打印出来

// echo "form Test say di2 name: ".$di2->sayName();

echo "form Test say di2 name: ";

echo $di2->sayName();

}

}

class DI{

private $name = "DI";

public function __construct(DI2 $di2){}

public function sayName(){

echo $this->name;

}

}

class DI2{

private $name = "DI2";

public function __construct(){}

public function sayName(){

echo $this->name;

}

}

class DI3{

private $name = "DI3";

public function __construct(){}

public function sayName(){

echo $this->name;

}

}

class DI4{

private $name = "DI4";

public function __construct(){}

public function sayName(){

echo $this->name;

}

}

//要不要无所谓了

// Container::bind('test','Test');

$test = Container::get('test');

$test->sayName();

echo "\n";

$test->sayDI2Name(new DI2());

echo "\n";

$di = Container::get('di');

$di->sayName();

echo "\n";

$di2 = Container::get('di2');

$di2->sayName();

echo "\n";

$di3 = new DI3();

Container::get('di3',$di3)->sayName();

echo "\n";

$di4 = function(){

return new DI4();

};

Container::get('di4',$di4)->sayName();

echo "\n";

?>

最后的结果如下

bVbpqb7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值