如何在PHP Attribute中获取被标注属性的类型?
PHP自定义Attribute获取标注属性的类型实现方案
需求场景
需要在自定义ObjectAttr注解中,获取被标注属性的类类型(如Bar::class或Boo::class),现有代码结构如下:
class Bar{ public int $id; } class Boo{ public string $name; } class Foo{ #[ObjectAttr] public Bar $barObject; #[ObjectAttr] public Boo $booObject; } #[Attribute] class ObjectAttr{ public function __construct(){ // 需要获取被标注属性的类型,比如返回Bar::class或Boo::class } }
实现思路
Attribute的构造函数无法直接获取目标属性的信息——因为Attribute实例是在解析注解时创建的,此时还未与目标元素绑定。必须通过PHP反射机制来遍历类属性、检查注解并提取类型信息。
完整实现步骤
- 明确指定
ObjectAttr的作用范围为属性,避免其他元素误用 - 使用
ReflectionClass遍历目标类的所有属性 - 检查每个属性是否带有
ObjectAttr注解 - 对符合条件的属性,通过反射获取其类型并提取类名
完整代码示例
class Bar{ public int $id; } class Boo{ public string $name; } class Foo{ #[ObjectAttr] public Bar $barObject; #[ObjectAttr] public Boo $booObject; } // 指定Attribute仅作用于属性 #[Attribute(Attribute::TARGET_PROPERTY)] class ObjectAttr{} // 封装获取逻辑的函数 function getAnnotatedPropertyTypes(string $className): array { $reflection = new ReflectionClass($className); $result = []; foreach ($reflection->getProperties() as $property) { // 检查属性是否带有ObjectAttr注解 $attributes = $property->getAttributes(ObjectAttr::class); if (!empty($attributes)) { $type = $property->getType(); // 确保类型是自定义类(而非PHP内置类型) if ($type instanceof ReflectionNamedType && !$type->isBuiltin()) { $result[$property->getName()] = $type->getName(); } } } return $result; } // 调用示例 $types = getAnnotatedPropertyTypes(Foo::class); print_r($types);
输出结果
Array ( [barObject] => Bar [booObject] => Boo )
补充说明
- 如果需要在
ObjectAttr内部处理类型信息,可以给ObjectAttr添加构造参数,在反射获取注解实例时主动注入类型信息 - 若属性允许为空(如
public ?Bar $barObject),可通过$type->allowsNull()判断,再处理实际的非空类型
内容的提问来源于stack exchange,提问作者Pejman
相关产品推荐
相关产品推荐

