反射在编程中是一个非常重要的概念,我理解的是,反射就是对目标函数、类、对象等构造结构的一种展现,并且利用反射API可以便捷的搭建一些基础类的设施(比如framework),对于反射最最常见的操作就是实例化对象,也许有人会说,我直接new一个对象不就OK了,为啥还需要这么繁琐的操作,没错,在我写这篇文章的时候其实也在思考这个问题,但是结合例子看起来,还是有区别的,如果我new一个我完全知道它内部结构的Class,那你这时再通过Reflection API去实例化确实有点脱裤子放屁的感觉,但是对于未知的一些对象实例化,就有些摸不着北了,因为你没办法知道这个将要被实例化的Class的construct方法具体需要传入哪些参数?而这时Reflection API就可以发挥很大的作用了~
以PHP为例,从5.0版本开始,PHP内置类引入了Reflection,并且包含众多的API,方便我们使用,下面介绍几种常见操作:
1、实例化对象: 针对构造方法中有参数的Class使用Reflection才有意义,没有参数确实直接new最方便
// 测试对象
class Person
{
private $name;
private $age;
public function __construct($name, $age)
{
$this->name = $name;
$this->age = $age;
}
public function updateAge($age)
{
$this->age = $age;
}
public function desc()
{
return "name: $this->name, age: $this->age";
}
}
// 实例化
$className = Person::class;
$classReflection = new \ReflectionClass($className);
$object = $classReflection->newInstanceArgs(['George', 18]);
2、`类成员方法` or `函数`参数分析: 类的成员方法其实跟函数是一样的,只是有些许的区别,函数能独立的生存,而类成员方法是需要依托于整个类,Reflection API中的也是这样设计的,类成员方法主要借助于ReflectionMethod这个API,而函数主要借助于ReflectionFunction,两者都继承自ReflectionFunctionAbstract这个抽象类,通过这个抽象类中的getParameters()可以分析出类成员方法或函数中入参名称、所属位置、默认值等信息(类型为ReflectionParameter),以下分别对类成员方法和函数进行举例说明:
// 类成员方法
$methodName = 'updateAge';
$methodReflection = new \ReflectionMethod($object, $methodName);
var_dump($methodReflection->getParameters()); // ReflectionParameter[]
// 函数
$function1 = function (Person $person) {
return $person->desc();
};
$reflection = new \ReflectionFunction($function1);
$reflectionParameters = $reflection->getParameters();
var_dump($reflectionParameters);
3、类成员属性分析: 有时类成员属性也需要我们动态的进行设置(注入),通过以下例子可以实现:
$property1 = new \ReflectionProperty($className, 'name');
if (!$property1->isPublic()) {
$property1->setAccessible(true);
}
$property1->setValue($object, 'George is not good!');
待补充…