反射在编程中是一个非常重要的概念,我理解的是,反射就是对目标函数、类、对象等构造结构的一种展现,并且利用反射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!');
待补充…