反射的常见操作 & 使用方法

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

待补充…

此条目发表在 涨姿势 分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*


*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>