PHP 所包含的反射 API,赋予了 PHP 代码一定程度的“自我分析”的能力。

一、定义

反射,顾名思义就是根据结果查找最初的起源,在 PHP 中,反射 API 可以被理解成一种可以提取 PHP 代码信息的类,这里“PHP 代码”具体可以是一个已经实例化的对象,也可以是未实例化的类或者类中的方法,使用反射 API 提供的方法,可以非常便捷的获取这些代码的“内在信息”,比如:获取已经实例化对象的原型类名,也可以获取某个类中的方法名列表,甚至可以获取与代码相关的注释信息,由此反射 API 的强大可见一斑。

二、使用

为了检查分析 PHP 代码中各种不同的数据类型,反射 API 包含了许多针对不同类型代码进行检查的类,具体可以参考 PHP 官方手册中关于反射 API 的部分。其中,一些常用的反射 API 类列举如下:

ReflectionClass:用于分析类信息

ReflectionObject:用于分析对象信息

ReflectionMethod:用于分析类中方法的相关信息

ReflectionParameter:用于分析方法的参数信息

ReflectionProperty:用于分析类属性的相关信息

ReflectionFunction:用于分析函数的相关信息

ReflectionExtension:用于分析扩展的相关信息

ReflectionException:用于分析异常错误代码的相关信息

三、举例

为了方便直观地理解反射 API 工作的具体过程,首先建立如下的 Person 类,并实例化为一个 star 对象:

class Person
{

    public $name;
    public $gender;
    public $age

    public function say()
    {
        echo 'my name is ' . $this->name;
        echo 'my gender is' . $this->gender;
        echo 'my age is' . $this->age;
    }

    public function laugh()
    {
        echo 'ha ha ha';
    }

    public function cry()
    {
        echo 'I am sad';
    }
}

$star = new Person();
$star->name   = 'messi';
$star->gender = 'male';
$star->age    = 29;

以下代码展示利用反射 API 来获取 star 对象中的方法和属性信息:

// 实例化一个ReflectionObject对象,传入参数为要分析的对象
$reflect = new ReflectionObject($star);

// 获取全部属性列表到数组中
$props = $reflect->getProperties();

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

// 获取全部方法信息到数组
$methods = $reflect->getMethods();

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

四、分析

PHP 官方文档中,列举了相当丰富的反射API类,利用这些类,几乎可以分析提取任何类型的 PHP 代码,利用这一特性,在实际的开发过程中,反射 API 通常用来为开发者生成说明文档,但值得注意的是,使用反射 API 的开销十分巨大,通常在逻辑代码的开发中,一般不推荐使用反射 API,反之,可以利用一些 PHP 自带的同样可以“自省”的全局函数来操作,这类函数的开销往往会远小于反射 API。

这一类同样可以提取代码信息的函数具体可以参考官方文档,下面列举了同样可以实现之前示例中反射 API 功能的常用函数:

get_class($object):获取对象的原型类

get_object_vars($object):获取对象的全部属性

get_class_vars($class):获取类中的属性列表

get_class_method($class):获取类中的方法列表