徐善通的随笔

千里之行, 始于足下



php反射类api的使用


PHP具有完整的反射API,可以对类、接口、函数、方法和扩展进行反向工程。反射API并提供方法取出函数、类和方法中的文档注释
简单来说, 给定一个类名, 可以提取到这个类的所有信息, 可以构建自动化文档, 可以通过分析参数来实现依赖注入

官方文档

总文档: https://www.php.net/manual/zh/book.reflection.php
类反射: https://www.php.net/manual/zh/class.reflectionclass.php

反射api的一些类

  • ReflectionClass 类信息和工具操作
  • ReflectionMethod 类方法和工具操作
  • ReflectionParameter 方法参数反射
  • ReflectionProperty 类属性反射
  • ReflectionFunction 函数反射
  • ReflectionExtension 扩展信息
  • ReflectionException 错误信息

类反射

要分析的类

namespace reflection;
/**
 * Class A
 */
class A {
    public $f1 = 1;
    protected $f2 = 2;
    private $f3 = 3;

    public function Foo()
    {

    }
}

interface Abc {

}

/**
 * Class B
 * this is class Doc
 */
class B extends A implements Abc{
    const TEST_1 = 1;

    const TEST_2 = 2;

    public $prop1 = 1;

    protected $prop2 = 2;

    private $prop3 = 3;

    public static $prop_static = [1];

    public function __construct()
    {
    }


    public function foo1(int $a,  int $b)
    {

    }

    public function foo2(int $a,  string $b)
    {

    }

    protected function foo3()
    {

    }

    private function foo4()
    {

    }
}
$obj = new B();

反射api

//$ref = new ReflectionClass($obj);
$ref = new \ReflectionClass(B::class);

//print_r(ReflectionClass::export(demo::class));
print_r($ref->getProperties()); // 获取一级属性, 可以传参数过滤, 返回ReflectionProperty 对象的数组。
var_dump($ref->getConstructor()); // 获取构造函数, 未定义返回null
var_dump($ref->inNamespace()); // 是否在命名空间中
var_dump($ref->getConstants()); // 获取所有定义的常量
var_dump($ref->getConstant('TEST_1')); // 获取某个常量
print_r($ref->getDefaultProperties()); // 获取默认属性, 返回数组, 包括父类的属性
var_dump($ref->getDocComment()); // 获取类文档注释, 不包含属性和方法的注释, 无注释返回false
var_dump($ref->getExtension()); // 获取获取最后一行的行数
var_dump($ref->getFileName()); // 获取定义类的文件名, 返回绝对路径
var_dump($ref->getInterfaceNames()); // 获取接口名称, 返回索引数组,值为接口名称, 未实现接口返回空数组
var_dump($ref->getInterfaces()); // 获取接口, 返回关联数组, name=>ReflectionClass实例, 未实现接口返回空数组
var_dump($ref->getMethods()); // 指获取类方法 ReflectionMethod。
var_dump($ref->getMethod('foo4')); // 获取一个类方法的 ReflectionMethod。如果方法不存在会抛出异常, 需要配合try catch一起用
var_dump($ref->getName()); // 获取类名, 包含命名空间
var_dump($ref->getNamespaceName()); // 获取命名空间的名称, 没有返回空
var_dump($ref->getParentClass()); // 获取父类reflectionClass的实例, 没有父类返回false
var_dump($ref->getProperty('prop3')); // 获取一个属性, 返回ReflectionProperty实例, 属性不存在会抛出异常, 需配合try catch使用
var_dump($ref->getShortName()); // 获取类名, 不包含命名空间
var_dump($ref->getStartLine()); // 获取起始行号
print_r($ref->getStaticProperties()); // 获取静态属性
print_r($ref->getStaticPropertyValue('prop_static')); // 获取静态属性值, 未定义的属性会报致命错误
print_r($ref->getTraitAliases()); // 返回 trait 别名的一个数组
print_r($ref->getTraitNames()); // 返回 trait 别名的一个数组
print_r($ref->getTraits()); // 返回这个类所使用的 traits 数组
var_dump($ref->hasConstant('AB')); // 检查常量是否已经定义
var_dump($ref->hasMethod('AB')); // 检查方法是否已经定义
var_dump($ref->hasProperty('AB')); // 检查属性是否已定义
var_dump($ref->implementsInterface('reflection\Abc')); // 检查是否实现了某个接口, 注意需要带上命名空间
var_dump($ref->isAbstract()); // 检查类是否是抽象类(abstract)
var_dump($ref->isAnonymous()); // 检查类是否是匿名类
var_dump($ref->isCloneable()); // 返回了一个类是否可复制
var_dump($ref->isFinal()); // 检查类是否声明为 final
var_dump($ref->isInstance($obj)); // 检查一个变量是否此类的实例
var_dump($ref->isInstantiable()); // 检查类是否可实例化
var_dump($ref->isInterface()); // 检查类是否是一个接口(interface)
var_dump($ref->isInternal()); // 检查类是否由扩展或核心在内部定义, 和isUserDefined相对
var_dump($ref->isIterateable()); // 检查此类是否可迭代, 实现了Iterator接口即可迭代
var_dump($ref->isSubclassOf(A::class)); // 是否是某一个类的子类
var_dump($ref->isTrait()); // 返回了是否为一个 trait
var_dump($ref->isUserDefined()); // 检查是否由用户定义的类 和isInternal相对

// 从指定的参数创建一个新的类实例,创建类的新的实例。给出的参数将会传递到类的构造函数。
// 接受可变数目的参数,用于传递到类的构造函数,和 call_user_func() 很相似。
var_dump($ref->newInstance());
// 从指定的参数创建一个新的类实例,创建类的新的实例。给出的参数将会传递到类的构造函数。
//这个参数以 array 形式传递到类的构造函数。
var_dump($ref->newInstanceArgs([]));
var_dump($ref->newInstanceWithoutConstructor()); // 创建一个新的实例而不调用他的构造函数
$ref->setStaticPropertyValue ('prop_static', '222'); // 设置静态属性的值, 无返回值
var_dump($ref->__toString ()); // 返回 ReflectionClass 对象字符串的表示形式。

作者: 徐善通
地址: https://www.xstnet.com/article-136.html
声明: 除非本文有注明出处,否则转载请注明本文地址


我有话说



最新回复


正在加载中....

Copyrights © 2016-2019 醉丶春风 , All rights reserved. 皖ICP备15015582号-1