反射机制简介

在面向对象编程中,对象被系统赋予了自省的能力,而实现这个自省的过程就是反射。
反射,简单理解就是根据目标物,得到目标物所携带的属性、技能等。在PHP中,我们可以通过反射对象,提取关于类、方法、属性、参数、注释等的详细信息。这种动态获取信息以及动态调用对象方法的功能称为反射API。
反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。比如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。
通过ReflectionClass,我们可以得到某个类的如下信息:

  1. 常量 Contants
  2. 属性 Property
  3. 方法 Method
  4. 属性 Static Properties
  5. 命名空间 Namespace
  6. 类的修饰,是否为final或者abstract

    使用

假设我们现在有一个这样的类:

  1. <?php
  2. class Student
  3. {
  4. public $name;
  5. protected $age;
  6. private $sex;
  7. public function __construct($name, $age, $sex)
  8. {
  9. $this->setName($name);
  10. $this->setAge($age);
  11. $this->setSex($sex);
  12. }
  13. public function setName($name)
  14. {
  15. $this->name = $name;
  16. }
  17. protected function setAge($age)
  18. {
  19. $this->age = $age;
  20. }
  21. private function setSex($sex)
  22. {
  23. $this->sex = $sex;
  24. }
  25. }

调用反射导出接口

  1. <?php
  2. \ReflectionClass::export(Student::class);

获取对象属性列表

  1. <?php
  2. $student = new Student('woodylan', 18, 1);
  3. $reflect = new ReflectionObject($student);
  4. $props = $reflect->getProperties();
  5. foreach ($props as $prop) {
  6. print $prop->getName() . "\n";
  7. }

获取对象方法列表

  1. <?php
  2. $methods = $reflect->getMethods();
  3. foreach ($methods as $prop) {
  4. print $prop->getName() . "\n";
  5. }

反射获取类的原型

  1. <?php
  2. $reflection = new ReflectionClass(Student::class);
  3. $className = $reflection->getName();
  4. $methods = [];
  5. $properties = [];
  6. foreach ($reflection->getProperties() as $value) {
  7. $properties[$value->getName()] = $value;
  8. }
  9. foreach ($reflection->getMethods() as $value) {
  10. $methods[$value->getName()] = $value;
  11. }
  12. echo "class {$className}\n{\n";
  13. is_array($properties) && ksort($properties);
  14. foreach ($properties as $key => $value) {
  15. echo "\t";
  16. echo $value->isPublic() ? ' public' : '', $value->isPrivate() ? ' private' : '',
  17. $value->isProtected() ? ' protected' : '',
  18. $value->isStatic() ? ' static' : '';
  19. echo "\t{$key}\n";
  20. }
  21. echo "\n";
  22. if (is_array($methods)) ksort($methods);
  23. foreach ($methods as $key => $value) {
  24. echo "\tfunction {$key}(){}\n";
  25. }
  26. echo "}\n";

其它API

反射不仅可以用于类和对象,还可以用于函数、扩展模块、异常等,官方提供了一系列的API方法,以下列举部分。
文档地址:http://php.net/manual/zh/book.reflection.php

ReflectionClass::__construct — 初始化 ReflectionClass 类

ReflectionClass::export — 导出一个类

ReflectionClass::getConstant — 获取定义过的一个常量

ReflectionClass::getConstants — 获取一组常量

ReflectionClass::getConstructor — 获取类的构造函数

ReflectionClass::getDefaultProperties — 获取默认属性

ReflectionClass::getDocComment — 获取文档注释

ReflectionClass::getEndLine — 获取最后一行的行数

ReflectionClass::getExtension — 根据已定义的类获取所在扩展的 ReflectionExtension 对象

ReflectionClass::getExtensionName — 获取定义的类所在的扩展的名称

ReflectionClass::getFileName — 获取定义类的文件名

ReflectionClass::getInterfaceNames — 获取接口(interface)名称

ReflectionClass::getInterfaces — 获取接口

ReflectionClass::getMethod — 获取一个类方法的 ReflectionMethod。

ReflectionClass::getMethods — 获取方法的数组

ReflectionClass::getModifiers — 获取类的修饰符

ReflectionClass::getName — 获取类名

ReflectionClass::getNamespaceName — 获取命名空间的名称

ReflectionClass::getParentClass — 获取父类

ReflectionClass::getProperties — 获取一组属性

ReflectionClass::getProperty — 获取类的一个属性的 ReflectionProperty

ReflectionClass::getReflectionConstant — Gets a ReflectionClassConstant for a class’s constant

ReflectionClass::getReflectionConstants — Gets class constants

ReflectionClass::getShortName — 获取短名

ReflectionClass::getStartLine — 获取起始行号

ReflectionClass::getStaticProperties — 获取静态(static)属性

ReflectionClass::getStaticPropertyValue — 获取静态(static)属性的值

ReflectionClass::getTraitAliases — 返回 trait 别名的一个数组

ReflectionClass::getTraitNames — 返回这个类所使用 traits 的名称的数组

ReflectionClass::getTraits — 返回这个类所使用的 traits 数组

ReflectionClass::hasConstant — 检查常量是否已经定义

ReflectionClass::hasMethod — 检查方法是否已定义

ReflectionClass::hasProperty — 检查属性是否已定义

ReflectionClass::implementsInterface — 接口的实现

ReflectionClass::inNamespace — 检查是否位于命名空间中

ReflectionClass::isAbstract — 检查类是否是抽象类(abstract)

ReflectionClass::isAnonymous — 检查类是否是匿名类

ReflectionClass::isCloneable — 返回了一个类是否可复制

ReflectionClass::isFinal — 检查类是否声明为 final

ReflectionClass::isInstance — 检查类的实例

ReflectionClass::isInstantiable — 检查类是否可实例化

ReflectionClass::isInterface — 检查类是否是一个接口(interface)

ReflectionClass::isInternal — 检查类是否由扩展或核心在内部定义

ReflectionClass::isIterable — Check whether this class is iterable

ReflectionClass::isIterateable — 检查是否可迭代(iterateable)

ReflectionClass::isSubclassOf — 检查是否为一个子类

ReflectionClass::isTrait — 返回了是否为一个 trait

ReflectionClass::isUserDefined — 检查是否由用户定义的

ReflectionClass::newInstance — 从指定的参数创建一个新的类实例

ReflectionClass::newInstanceArgs — 从给出的参数创建一个新的类实例。

ReflectionClass::newInstanceWithoutConstructor — 创建一个新的类实例而不调用它的构造函数

ReflectionClass::setStaticPropertyValue — 设置静态属性的值

ReflectionClass::__toString — 返回 ReflectionClass 对象字符串的表示形式。