PHP反射机制Reflection

反射机制简介

在面向对象编程中,对象被系统赋予了自省的能力,而实现这个自省的过程就是反射。

​反射,简单理解就是根据目标物,得到目标物所携带的属性、技能等。在PHP中,我们可以通过反射对象,提取关于类、方法、属性、参数、注释等的详细信息。这种动态获取信息以及动态调用对象方法的功能称为反射API。

反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。比如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

通过ReflectionClass,我们可以得到某个类的如下信息:

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

使用

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

class Student
{
    public $name;
    protected $age;
    private $sex;

    public function __construct($name, $age, $sex)
    {
        $this->setName($name);
        $this->setAge($age);
        $this->setSex($sex);
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    protected function setAge($age)
    {
        $this->age = $age;
    }

    private function setSex($sex)
    {
        $this->sex = $sex;
    }
}

调用反射导出接口:

\ReflectionClass::export(Student::class);

导出结果:

/**
 * User: wooylan
 * Date: 2019/3/11
 * Time: 21:59
 */
Class [  class Student ] {
  @@ /path/reflection.php 8-35

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [3] {
    Property [  public $name ]
    Property [  protected $age ]
    Property [  private $sex ]
  }

  - Methods [4] {
    Method [  public method __construct ] {
      @@ /path/reflection.php 14 - 19

      - Parameters [3] {
        Parameter #0 [  $name ]
        Parameter #1 [  $age ]
        Parameter #2 [  $sex ]
      }
    }

    Method [  public method setName ] {
      @@ /path/reflection.php 21 - 24

      - Parameters [1] {
        Parameter #0 [  $name ]
      }
    }

    Method [  protected method setAge ] {
      @@ /path/reflection.php 26 - 29

      - Parameters [1] {
        Parameter #0 [  $age ]
      }
    }

    Method [  private method setSex ] {
      @@ /path/test.php 31 - 34

      - Parameters [1] {
        Parameter #0 [  $sex ]
      }
    }
  }
}

获取对象属性列表

$student = new Student('woodylan', 18, 1);
$reflect = new ReflectionObject($student);
$props = $reflect->getProperties();
foreach ($props as $prop) {
    print $prop->getName() . "\n";
}

输出:

name
age
sex

获取对象方法列表

$methods = $reflect->getMethods();
foreach ($methods as $prop) {
    print $prop->getName() . "\n";
}

输出:

__construct
setName
setAge
setSex

反射获取类的原型

$reflection = new ReflectionClass(Student::class);
$className = $reflection->getName();
$methods = [];
$properties = [];

foreach ($reflection->getProperties() as $value) {
    $properties[$value->getName()] = $value;
}

foreach ($reflection->getMethods() as $value) {
    $methods[$value->getName()] = $value;
}

echo "class {$className}\n{\n";
is_array($properties) && ksort($properties);
foreach ($properties as $key => $value) {
    echo "\t";
    echo $value->isPublic() ? ' public' : '', $value->isPrivate() ? ' private' : '',
    $value->isProtected() ? ' protected' : '',
    $value->isStatic() ? ' static' : '';
    echo "\t{$key}\n";
}
echo "\n";
if (is_array($methods)) ksort($methods);
foreach ($methods as $key => $value) {
    echo "\tfunction {$key}(){}\n";
}
echo "}\n";

输出:

class Student
{
    protected   age
    public      name
    private     sex

    function __construct(){}
    function setAge(){}
    function setName(){}
    function setSex(){}
}

其它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 对象字符串的表示形式。

来源:https://www.wugenglong.com/php/php_reflection.html

你可能感兴趣的:(PHP反射机制Reflection)