<?php class People { public $dog = null; public function __construct() { $this->dog = new Dog(); } public function putDog(){ return $this->dog->dogCall(); } } class Dog{ public function dogCall(){ return 'go to home....'; } } class Container { /** * 容器绑定,用来装提供的实例或者 提供实例的回调函数 * @var array */ public $building = []; /** * 注册一个绑定到容器 */ public function bind($abstract, $concrete = null, $shared = false) { if(is_null($concrete)){ $concrete = $abstract; } if(!$concrete instanceOf Closure){ $concrete = $this->getClosure($abstract, $concrete); } $this->building[$abstract] = compact("concrete", "shared"); print_r($this->building); // $res = ($this->building)['Dog']['concrete']; // print_r($res);die; // var_dump($res instanceof Closure);die; } //注册一个共享的绑定 单例 public function singleton($abstract, $concrete, $shared = true){ $this->bind($abstract, $concrete, $shared); } /** * 默认生成实例的回调闭包 * * @param $abstract * @param $concrete * @return Closure */ public function getClosure($abstract, $concrete) { return function($c) use($abstract, $concrete){ $method = ($abstract == $concrete)? 'build' : 'make'; print_r($method.PHP_EOL); return $c->$method($concrete); }; } /** * 生成实例 */ public function make($abstract) { $concrete = $this->getConcrete($abstract); $data = $this->isBuildable($concrete, $abstract); // print_r($concrete);die; if( $data ){ $object = $this->build($concrete); }else{ $object = $this->make($concrete); } return $object; } /** * 获取绑定的回调函数 */ public function getConcrete($abstract) { // if(! isset($this->building[$abstract]) ){ // return $abstract; // } if( is_object($abstract) ){ return $abstract; } return $this->building[$abstract]['concrete']; } /** * 判断 是否 可以创建服务实体 */ public function isBuildable($concrete, $abstract) { return $concrete === $abstract || $concrete instanceof Closure; } /** * 根据实例具体名称实例具体对象 */ public function build($concrete) { if($concrete instanceof Closure){ return $concrete($this); } //创建反射对象 $reflector = new \ReflectionClass($concrete); print_r($reflector); if( ! $reflector->isInstantiable()){ //抛出异常 throw new \Exception('error.'); } $constructor = $reflector->getConstructor(); print_r($constructor); if(is_null($constructor)){ return new $concrete; } $dependencies = $constructor->getParameters(); print_r($dependencies); $instance = $this->getDependencies($dependencies); print_r( $reflector->newInstanceArgs($instance) ); return $reflector->newInstanceArgs($instance); } //通过反射解决参数依赖 public function getDependencies(array $dependencies) { $results = []; foreach( $dependencies as $dependency ){ $results[] = is_null($dependency->getClass()) ?$this->resolvedNonClass($dependency) :$this->resolvedClass($dependency); } return $results; } //解决一个没有类型提示依赖 public function resolvedNonClass(ReflectionParameter $parameter) { if($parameter->isDefaultValueAvailable()){ return $parameter->getDefaultValue(); } throw new \Exception('error_one.'); } //通过容器解决依赖 public function resolvedClass(ReflectionParameter $parameter) { return $this->make($parameter->getClass()->name); } } $app = new Container(); $app->bind('Dog','Dog'); $app->bind('People', 'People'); $people = $app->make('People'); echo $people->putDog(); ?>