一、官方解释

自PHP5版本后,PHP具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。

二、首先,我们先来了解反射是什么?

它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。

其应用场景如:

自动加载插件;

自动生成文档;

依赖注入;

对象池;

动态调用对象的方法,对象方法参数的检测等;

用来扩充PHP语言。

PHP反射API由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了那些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。 反射API是PHP内建的OOP技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些OOP扩展被称为反射。

我们用的比较多的是 ReflectionClass类、ReflectionObject 和ReflectionMethod类,

ReflectionClass 通过类名获取类的信息;

ReflectionObject 通过类的对象获取类的信息;

ReflectionMethod 获取一个方法的有关信息。

其他的还有

ReflectionException类

ReflectionFunction类

ReflectionExtension类

ReflectionFunctionAbstract 类

ReflectionGenerator类

ReflectionParameter 类

ReflectionProperty类

ReflectionType类

三、ReflectionClass,获取User类的属性及方法信息

User类

<?php

class User
{
    /**
     * 性别常量,1代表男,2代表女
     */
    const USER_GENDER_1 = 1;
    const USER_GENDER_2 = 2;

    /**
     * 创建静态私有的变量保存该类对象
     */
    private static $instance;
    /**
     * 用户全局唯一id
     *
     * @var string
     */
    protected $globalId;
    /**
     * 用户姓名
     *
     * @var string
     */
    protected $name;
    /**
     * 用户性别,1男;2女
     *
     * @var int
     */
    protected $gender;
    /**
     * 用户手机号
     *
     * @var string
     */
    protected $mobile;

    /**
     * @return string
     */
    public function getGlobalId(): string
    {
        return $this->globalId;
    }

    /**
     * @param string $globalId
     */
    public function setGlobalId(string $globalId): void
    {
        $this->globalId = $globalId;
    }

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName(string $name): void
    {
        $this->name = $name;
    }

    /**
     * @return int
     */
    public function getGender(): int
    {
        return $this->gender;
    }

    /**
     * @param int $gender
     */
    public function setGender(int $gender): void
    {
        $this->gender = $gender;
    }

    /**
     * @return string
     */
    public function getMobile(): string
    {
        return $this->mobile;
    }

    /**
     * @param string $mobile
     */
    public function setMobile(string $mobile): void
    {
        $this->mobile = $mobile;
    }

    /**
     * 获取用户的单例实现
     * @return User
     */
    public static function getInstance()
    {
        //判断实例有无创建,没有的话创建实例并返回,有的话直接返回
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

}
PHP
$className = "User";
$class = new ReflectionClass($className); // 建立User类的反射类
$instance  = $class->newInstanceArgs(); // 相当于实例化User类

var_dump($class);
var_dump($instance);

$properties = $class->getProperties();

var_dump($properties);

foreach ($properties as $property) {
    echo $property->getName() . "\n";
}

$private_properties = $class->getProperties(ReflectionProperty::IS_PRIVATE);
var_dump($private_properties);


foreach ($properties as $property) {
    if ($property->isProtected()) {
        $docblock = $property->getDocComment();
        echo $docblock."\n";
    }
}

$methods = $class->getMethods();
var_dump($methods);

$isExistMethod = $class->hasMethod("setMobile");
var_dump($isExistMethod);
$isExistMethod = $class->hasMethod("test");
var_dump($isExistMethod);

$method = $class->getMethod("setMobile");
var_dump($method);


//设置用户姓名
$method = $class->getmethod('setName');// 获取User类中的setName方法
$method->invokeArgs($instance, ["joshua317"]);

//获取用户姓名
$method = $class->getmethod('getName');// 获取User类中的getName方法
$userName = $method->invoke($instance);//执行getName 方法
var_dump($userName);


$method = new ReflectionMethod('User', 'setName');
if ($method->isPublic() && !$method->isStatic()) {
    echo "function is protected";
}

相关文章: