【问题标题】:Is the newInstance method fast with little footprint to use in PHP 8 ReflectionAttribute class?在 PHP 8 ReflectionAttribute 类中使用 newInstance 方法是否快速且占用空间小?
【发布时间】:2021-02-04 00:47:43
【问题描述】:

在 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 = ''
    ){}
}

And 用于属性如下

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

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

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

有可能吗?

【问题讨论】:

    标签: php php-8


    【解决方案1】:

    似乎还没有人为ReflectionAttribute 类编写文档,但您可以看到a summary in the feature proposal for Attributes,其中列出了它的方法:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-21
      • 2011-07-05
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 2015-05-25
      • 2015-06-22
      相关资源
      最近更新 更多