学习依赖注入和反射应该弄懂以下几个概念:
依赖倒置原则:程序要依赖于抽象接口,不要依赖于具体实现。
控制反转:遵循依赖倒置原则的一种代码设计方案,依赖的创建 (控制) 由主动变为被动 (反转)。
依赖注入:控制反转的一种具体实现方法。通过参数的方式从外部传入依赖,将依赖的创建由主动变为被动 (实现了控制反转)。
反射:提供能够知道类是如何被定义的,它有什么属性、什么方法、方法都有哪些参数,类文件的路径是什么等很重要的信息。
认识从反射开始:
class boy{
public $name = "bbb";
public function __set($name, $value){
echo "设置私有属性".PHP_EOL;
$this->$name = $value;
}
public function __get($name){
echo "获取私有属性".PHP_EOL;
return $this->$name;
}
public function action(){
echo "吃饭";
}
}
//实例化类
$reflect = new ReflectionClass(boy::class);
//获取类属性
$props = $reflect->getProperties();
var_dump($props);
echo PHP_EOL;
// 获取反射实例的构造方法
$constructor = $reflect->getConstructor();
var_dump($constructor);
$prams = $constructor->getParameters();
var_dump($prams);
//获取类方法
$metheds = $reflect->getMethods();
var_dump($metheds);
echo PHP_EOL;
//获取方法参数
$prams = $reflect->getMethod('__set')->getParameters();
var_dump($prams);
以上就是对反射的简单了解。
下面我们看戏容器是什么鬼??
首先回顾下上边讲的概念:程序依赖接口,就是类提供的方法,不依赖方法的实现。将具体的实现接口通过反射,以参数的方式从外部注入到使用类里面。讲解的还不够清楚,直接看代码吧
//主要函数实现
static function make($class){
$reflect = new ReflectionClass($class);
//判断能否实列化
if(!$reflect->isInstantiable()){
throw new Exception('不能实列化!');
}
//判断有没有__constructor魔法函数
$constructor = $reflect->getConstructor();
if(is_null($constructor)){
return new $class();
}
//获取参数
$params = $reflec->getParameters();
//处理依赖关系
$dependentis = [];
foreach($params as $key => $param){
//获取类
$className = $param->getClass();
//获取参数
$paramName = $param->getName();
if(is_null($className)){
if($className->isDefaultValueAvailable()){
$dependentis[] = dependenci->getDefaultValue();
}else{
throw new Exception($paramName . ' 参数没有默认值');
}
}else{
$dependentis[] = self::make($className->getName());
}
}
// 获得构造函数的数组之后就可以实例化了
return $reflect->newInstanceArgs($dependencies);
}
源代码,欢迎查看指正
网友评论