<?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();
?>