ReflectionClass 是 PHP 8.0 反射核心,可获取类名、父类、接口、属性、方法等元信息;支持字符串类名或实例初始化,需注意自动加载与异常捕获。

用 ReflectionClass 获取类的基本结构
PHP 8.0 的反射机制核心是 ReflectionClass,它能读取类名、父类、接口、属性、方法等元信息。直接传入类名字符串或对象实例即可初始化:
- 传字符串:
new ReflectionClass('DateTime')—— 注意类必须已加载(自动加载或require过) - 传实例:
new ReflectionClass(new MyClass())—— 更安全,避免类未定义导致的ReflectionException - 获取类名建议用
$ref->getName(),而不是硬编码字符串,尤其在泛型或动态场景中
检查类是否为 final、abstract 或 implements 某接口
PHP 8.0 中这些判断方法行为稳定,但要注意返回值类型是布尔值,不是字符串标识:
-
$ref->isFinal()返回true表示不能被继承 -
$ref->isAbstract()对抽象类返回true,哪怕它没声明任何 abstract 方法(只要含 abstract 方法或自身声明为 abstract) -
$ref->implementsInterface('JsonSerializable')接收接口名字符串,支持完全限定名(如'\JsonSerializable'),不加命名空间前缀可能失败 - 注意:
$ref->getInterfaces()返回的是ReflectionClass数组,不是接口名列表;要取名字得遍历调用->getName()
读取属性和方法时绕过访问控制限制
反射能无视 private 和 protected,但需显式调用 setAccessible(true) 才能读取值或调用 —— 这点在 PHP 8.0 没变,但错误常出在漏掉这步:
- 获取所有属性(含 private/protected):
$ref->getProperties(),返回ReflectionProperty对象数组 - 想读 private 属性值?先
$prop->setAccessible(true),再$prop->getValue($instance);否则抛ReflectionException - 同理,调用 private 方法:
$method->setAccessible(true); $method->invoke($instance, ...$args) - PHP 8.0 不再允许对未设置
setAccessible(true)的私有成员执行读写操作,报错更严格
PHP 8.0 特有的兼容性注意点
PHP 8.0 引入了联合类型、属性类型、构造函数属性提升等特性,反射会如实暴露这些信息,但部分旧代码可能误判:
立即学习“PHP免费学习笔记(深入)”;
-
$prop->getType()在 PHP 8.0 返回ReflectionNamedType或ReflectionUnionType实例,不再是字符串;需用->getName()或->__toString()提取类型名 - 构造函数参数若用了属性提升(
public function __construct(private string $name) {}),对应属性会出现在getProperties()结果里,且$prop->getDeclaringClass()指向当前类而非构造函数 - 匿名类反射可用,但
$ref->getName()返回类似"class@anonymous/in/file.php:12"的临时名,不可用于class_exists()
反射本身不触发自动加载失败的 fatal error,但 new ReflectionClass('UnknownClass') 会抛 ReflectionException,务必 try/catch。



















