直接 new ReflectionClass 可获取类元信息而不执行构造逻辑;需传完整命名空间或对象实例,用 getMethods() 和 getProperties() 获取结构,getDocComment() 提取紧邻 PHPDoc 注释,读私有属性须先 setAccessible(true),PHP 8.1+ 对敏感属性有限制。

直接 new ReflectionClass 能拿到什么
它不执行构造函数,只读取类定义本身。哪怕 __construct() 里写了 die() 或 require 'missing.php',只要类名能被自动加载器识别,反射就能成功。
常见失败点是传错命名空间:比如在 PSR-4 下写 new ReflectionClass('User'),大概率报 Class User not found;得写成 new ReflectionClass('App\Models\User')。更稳妥的做法是传实例:new ReflectionClass($user),自动推导完整类名,避开字符串拼写风险。
类不存在会抛 ReflectionException,建议先用 class_exists() 判断,或用 try/catch 包裹。
getMethods() 返回哪些方法、怎么过滤
getMethods() 默认返回所有非静态方法(public/protected/private),但不含 static 方法。要包含静态方法,得显式传参:$ref->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC)。
立即学习“PHP免费学习笔记(深入)”;
常用过滤组合:
-
ReflectionMethod::IS_PUBLIC:只取 public 方法 -
ReflectionMethod::IS_PROTECTED:只取 protected 方法 -
ReflectionMethod::IS_PRIVATE:只取 private 方法 - 用按位或
|组合多个标志,比如IS_PUBLIC | IS_PROTECTED
注意:getMethods() 不区分“本类定义”和“继承来的方法”。如果只想看当前类声明的方法(不含父类),得手动比对:$method->getDeclaringClass()->getName() === $ref->getName()。
读 PHPDoc 注释必须紧邻且格式正确
getDocComment() 只认紧贴在类、方法或属性声明正上方的 /** ... */ 块,中间不能有空行。缩进和换行不影响,但写成 // 或 /* */ 风格一律返回 null。
类注释:直接调 $ref->getDocComment();方法注释:先 $method = $ref->getMethod('store'),再 $method->getDocComment()。
返回的是完整字符串(含 /** 和 */),想提取 @param 或 @return 得自己用 preg_match() 解析,或者引入轻量 docblock 库。
访问 private 属性必须 setAccessible(true)
不能直接 $prop->getValue($obj),否则报 Cannot access private property。必须先调 $prop->setAccessible(true) 打开通道。
PHP 8.1+ 对敏感属性加了 #[\SensitiveParameter] 标记,即使设了 setAccessible(true),读取时也会触发警告或拒绝——这点容易忽略,尤其在处理用户输入或凭证字段时。
调用私有方法同理:$method->setAccessible(true) 后才能 $method->invoke($obj),但要注意参数类型提示是否可实例化(比如传 interface 类型参数会立刻失败,不是延迟报错)。
实际用反射时,最常被绕过的其实是命名空间拼写和 PHPDoc 空行限制;而 PHP 8.1+ 的敏感标记,则是升级后突然失效的隐形坑。



















