下面给你一份清晰 + 可直接使用的讲解,完整说明
👉 PHP 中如何使用反射获取类的所有方法
一、什么是 PHP 反射(Reflection)?
反射允许你在运行时检查类、方法、属性、参数等结构信息,而不需要提前写死。
常见用途:
- 框架自动注入(Laravel / Hyperf)
- 注解 / Attribute 解析
- AOP(切面)
- 自动路由、自动文档
- 单元测试、Mock
二、最基础:获取一个类的所有方法
示例 1:获取全部方法(包含父类)
class Demo {
public function foo() {}
protected function bar() {}
private function baz() {}
}
$ref = new ReflectionClass(Demo::class);
$methods = $ref->getMethods();
foreach ($methods as $method) {
echo $method->getName() . PHP_EOL;
}
📌 结果包含:
- public / protected / private
- 父类方法
三、按可见性筛选方法(最常用)
只获取 public 方法
$methods = $ref->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($methods as $method) {
echo $method->getName();
}
组合筛选(public + protected)
$methods = $ref->getMethods(
ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
);
四、只获取“当前类”定义的方法(排除父类)
$methods = array_filter(
$ref->getMethods(),
fn($m) => $m->getDeclaringClass()->getName() === Demo::class
);
foreach ($methods as $method) {
echo $method->getName() . PHP_EOL;
}
五、获取方法的详细信息(进阶)
foreach ($ref->getMethods() as $method) {
echo "方法名: " . $method->getName() . PHP_EOL;
echo "是否 public: " . $method->isPublic() . PHP_EOL;
echo "是否 static: " . $method->isStatic() . PHP_EOL;
echo "参数数量: " . $method->getNumberOfParameters() . PHP_EOL;
echo "声明类: " . $method->getDeclaringClass()->getName() . PHP_EOL;
echo "----------------" . PHP_EOL;
}
六、获取方法参数信息
$method = $ref->getMethod('foo');
foreach ($method->getParameters() as $param) {
echo $param->getName();
if ($param->hasType()) {
echo ' : ' . $param->getType();
}
if ($param->isOptional()) {
echo ' = ' . $param->getDefaultValue();
}
echo PHP_EOL;
}
七、获取注解 / Attribute(PHP 8+)
示例:Attribute 定义
#[Attribute]
class Route {
public function __construct(public string $path) {}
}
使用反射读取
class Controller {
#[Route('/user')]
public function index() {}
}
$method = (new ReflectionClass(Controller::class))
->getMethod('index');
$attrs = $method->getAttributes(Route::class);
foreach ($attrs as $attr) {
$instance = $attr->newInstance();
echo $instance->path;
}
八、常见实战场景示例
1️⃣ 自动路由扫描
$controller = new ReflectionClass(UserController::class);
foreach ($controller->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if (! $method->isConstructor()) {
echo "注册路由: " . $method->getName();
}
}
2️⃣ 扫描可调用 API
$methods = array_filter(
$ref->getMethods(ReflectionMethod::IS_PUBLIC),
fn($m) => !str_starts_with($m->getName(), '__')
);
九、常见坑点(一定要看)
❌ getMethods() 默认包含父类
❌ private 方法默认也会返回
❌ 反射比普通调用慢(但框架都会缓存)
❌ 匿名类 / Trait 行为不同
十、快速对照表
| 需求 | 方法 |
|---|---|
| 所有方法 | getMethods() |
| public 方法 | IS_PUBLIC |
| 当前类方法 | getDeclaringClass() |
| 参数信息 | getParameters() |
| 注解 | getAttributes() |
十一、一句话总结
Reflection 是 PHP 框架的“显微镜”,能让代码在运行时看见自己
发表回复