1

在 PHP 8 中,引入了 ReflectionAttribute 类。它类似于 Java、Typescripts 等中的注解。例如,每次您想使用属性的属性时,您必须执行以下操作:

$attributeReflection = ...;
...
$attribute = $attributeReflection->newInstance();
$message = $attribute->getMessage();

$attributeReflection 是 ReflectionAttribute 的一个实例。属性本身如下:

#[Attribute(Attribute::ALL)]
class MyAttribute{
    public function __construct(
        public ?string $message = ''
    ){}
}

并按如下方式用于属性

class Foo{
    #[MyAttribute("my message")
    public ?string $id = null;
}

如您所见,每次我想获取属性的消息时,我都必须创建它的一个新实例。虽然对于这种情况,消息永远不会改变。

我正在寻找一种避免新实例并使用共享实例的方法。

可能吗?

4

1 回答 1

1

似乎还没有人为ReflectionAttribute该类编写文档,但您可以在 Attributes 的功能提案中看到一个摘要,其中列出了它的方法:

class ReflectionAttribute
{
    public function getName(): string { ... }
    public function getArguments(): array { ... }
    public function newInstance(): object { ... }
}

这里的关键是你可以在调用构造函数的情况下访问参数——事实上,属性名甚至不需要是一个有效的类名,因为在newInstance调用之前它不会被自动加载。

因此,在您的示例中,您可以简单地说$message = $attributeReflection->getArguments()[0],或编写一个自定义工厂,将具有相同消息的实例合并等。

另一方面,请注意过早的优化:只有在分析告诉您这实际上是您的应用程序的重大成本时,才花时间使这更复杂。您可能会发现反射本身比构造函数调用的成本要高得多,并决定在构建脚本中运行整个事情,将运行时所需的信息保存到某种缓存中。

于 2021-02-04T13:01:47.847 回答