lumen-ioc容器测试 (3)
接上篇
问题一,如果想通过同一个类名,获取不同的对象,而不是单例对象怎么办?
// 省略的上篇容器代码
class Person { public $name; } $container = new Container(); $container->bind("person",function(){ return new Person(); }); $zhangsan = $container->make("person"); $zhangsan->name = "zhangsan"; $lisi = $container->make("person"); $lisi->name = "lisi"; echo $zhangsan->name."<br>"; echo $lisi->name."<br>";
//结果
lisi
lisi
如何解决 可以设置一个shared的参数 绑定的时候,如果是真 那么表示要共享,就存储到已解析数组里面 否则不存
<?php class Container { // 调用bind方法绑定过的对象 private $bindings = []; // 执行了bind并且执行了回调 存储的是实例化过的对象 可以直接使用 private $instance = []; /** * 绑定 * @param $abstract bind的名称 * @param $concrete 回调 */ public function bind($abstract, $concrete, $shared = false) { $this->bindings[$abstract] = [ 'concrete' => $concrete, 'shared'=> $shared ]; } /** * 根据绑定名称 获取实例 * @param $abstract 名称 */ public function make($abstract) { if(!isset($this->bindings[$abstract])){ throw new \Exception($abstract." 未绑定到容器"); } if(isset($this->instance[$abstract])){ return $this->instance[$abstract]; } $obj = $this->bindings[$abstract]['concrete'](); // 如果需要共享 那么才存进容器已经解析里面 if($this->bindings[$abstract]['shared']){ $this->instance[$abstract] = $obj; } return $obj; } } class Person { public $name; } $container = new Container(); // 第二个是否共享参数false表示不共享 每次都新实例化对象 $container->bind("person",function(){ return new Person(); }); $zhangsan = $container->make("person"); $zhangsan->name = "zhangsan"; $lisi = $container->make("person"); $lisi->name = "lisi"; echo $zhangsan->name; // zhangsan echo $lisi->name; // lisi var_dump($zhangsan); // object(Person)#3 (1) { ["name"]=> string(8) "zhangsan" } var_dump($lisi); // object(Person)#4 (1) { ["name"]=> string(4) "lisi" }