You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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反射机制来遍历类属性、检查注解并提取类型信息。

完整实现步骤

  1. 明确指定ObjectAttr的作用范围为属性,避免其他元素误用
  2. 使用ReflectionClass遍历目标类的所有属性
  3. 检查每个属性是否带有ObjectAttr注解
  4. 对符合条件的属性,通过反射获取其类型并提取类名

完整代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:10:33