<?php
interface KeyBoard{
public function make();
}
interface Mouse{
public function make();
}
class MechanicalKeyboard implements KeyBoard
{
public function make(){
echo '机械键盘正在work';
}
}
class CommonKeyboard implements KeyBoard
{
public function make(){
echo '普通键盘正在work';
}
}
class CommonMouse implements Mouse
{
public function make(){
echo '普通鼠标正在work';
}
}
class Computer
{
protected $keyBoard;
protected $mouse;
public function __construct(KeyBoard $keyBoard,Mouse $mouse)
{
$this->keyBoard = $keyBoard;
$this->keyBoard->make();
$this->mouse = $mouse;
$this->mouse->make();
}
}
class Container
{
private $binds;
//将接口和类名保存到binds中
public function bind($contract,$concrete)
{
$this->binds[$contract] = $concrete;
}
//获取到指定方法的注入参数,默认方法是采用__construct进行注入
public function methodBindParams($className)
{
$reflect = new Reflect($className,'__construct');
return $reflect->bindParamsToMethod();
}
//实例化类
public function make($className)
{
//获取需要实例化类所需要的必要参数
$methodBindParams = $this->methodBindParams($className);
//实例化类反射类
$reflect = new Reflect($className,'__construct');
//实例化类,插入实例化所需要的参数和参数接口对应的类
return $reflect->make($this->binds,$methodBindParams);
}
}
class Reflect
{
private $className;
private $methodName;
public function __construct($className,$methodName)
{
$this->className = $className;
$this->methodName = $methodName;
}
public function bindParamsToMethod()
{
$params = [];
//获取到类的方法信息
$method = new ReflectionMethod($this->className,$this->methodName);
//将类方法参数信息保存到params中
foreach ($method->getParameters() as $param){
$params[] = [
//参数名称
$param->name,
//参数是哪个类型
$param->getClass()->name
];
}
//返回这个类--》方法的参数
return [$this->className => $params];
}
public function make($bind,$methodBindParams)
{
$args = [];
//遍历类-》参数列表
foreach ($methodBindParams as $className => $params){
//遍历参数列表
foreach ($params as $param){
//获取到参数名和参数类型(是哪个接口)
list($paramName,$paramType) = $param;
//实例化对应接口的实现的类
$paramName = new $bind[$paramType]();
//将实例化后的类放到args列表中
array_push($args,$paramName);
}
}
//实例化反射
$reflectionClass = new ReflectionClass($this->className);
//从给定参数生成一个实例
return $reflectionClass->newInstanceArgs($args);
}
}
$container = new Container();
$container->bind('KeyBoard','CommonKeyBoard');
$container->bind('Mouse','CommonMouse');
$container->make('Computer');