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)
:获取类中的方法列表