<?php
interface Animal{
public function attack();
public function talk();
}
class People implements Animal
{
public $month;
public $hand;
public function __construct(Mouth $mouth,Hand $hand)
{
$this->month = $mouth;
$this->hand = $hand;
}
public function attack()
{
$this->hand->scrap();
}
public function talk()
{
$this->month->say();
}
}
class Mouth{
public function say(){
echo "咿咿呀呀";
}
}
class Hand{
public $finger;
public function __construct(Finger $finger)
{
$this->finger = $finger;
}
public function scrap(){
echo '仍玩具';
}
public function otherFunction(){
$this->finger->eatFinger();
}
}
class Finger{
public function eatFinger(){
echo "吃手指";
}
}
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");
}
//注册一个共享的绑定 单例
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';
return $c->$method($concrete);
};
}
/**
* 生成实例
*/
public function make($abstract){
$concrete = $this->getConcrete($abstract);
if($this->isBuildable($concrete, $abstract)){
$object = $this->build($concrete);
}else{
$object = $this->make($concrete);
}
return $object;
}
/**
* 获取绑定的回调函数
*/
public function getConcrete($abstract){
if(! isset($this->building[$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);//通过反射获取类名
if( ! $reflector->isInstantiable()){
//抛出异常
throw new Exception('无法实例化');
}
$constructor = $reflector->getConstructor();//获取构造函数
if(is_null($constructor)){
return new $concrete;
}
$dependencies = $constructor->getParameters();//获取构造函数参数
$instance = $this->getDependencies($dependencies);
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('出错');
}
//通过容器解决依赖
public function resolvedClass(ReflectionParameter $parameter)
{
return $this->make($parameter->getClass()->name);
}
}
//实例化容器类
$container = new Container();
$container->bind('Animal','People');//将需要创建对象的类放到容器中
$people = $container->make('Animal');//创建对象
$people->attack();//调用方法
$people->talk();