【问题标题】:Is it possible to implement an interface with PHP 8 attribute and check if it is an instance of that interface?是否可以使用 PHP 8 属性实现接口并检查它是否是该接口的实例?
【发布时间】:2021-02-03 22:30:05
【问题描述】:

我有一个 PHP 属性如下:

#[Attribute(Attribute::TARGET_PROPERTY|Attribute::TARGET_METHOD|Attribute::TARGET_PARAMETER)]
class NotNull implements Constraint{
 ...
}

现在,我想获取属性反射的所有属性的列表并检查它们是否是约束的实例:

$propertyReflection = ...;
$attributes = $propertyReflection->getAttributes();
foreach($attributes as $attribute){
    if($attribute instanceof Constraint){
         // do something
    }
}

但是,它什么都不做?

那么,我的问题是:是否可以用一个属性实现一个接口,然后检查该属性是否是一个实例?


这是完整的代码:

$reflection = new ReflectionClass($type);
$properties = $reflection->getProperties();
foreach ($properties as $property) {
    $attributes = $property->getAttributes();
    foreach ($attributes as $attribute) {
        if (attribute instanceof Constraint)) {
            // do something
        }
    }
}

【问题讨论】:

  • $propertyReflection = ...; 这行实际上说了什么?我假设您使用的是反射器而不是实际的对象?

标签: php reflection php-8


【解决方案1】:

这不起作用,因为 $attribute 是一个 ReflectionAttribute 对象,它还不是您的 NotNull 类的实例。要解决此问题,您需要对其进行实例化,然后检查它是否是正确的实例。

if($attribute->newInstance() instanceof Constraint)
    // do something

您可以在 3v4l.org 看到它正在运行。


如果您出于任何特定原因不想实例化它,因为它会做您认为不必要的事情,您还可以使用更多reflection techniques 来检查该属性是您期望的类。

(new ReflectionClass($attribute->getName()))
    ->implementsInterface(Constraint::class)

3v4l.org查看此工作

【讨论】:

  • 谢谢,您节省了我的时间。要知道,PHP8 文档并没有涵盖所有部分的新特性。
  • 文档中有很多内容,但并不具体,您必须真正调试,然后在进行过程中进行研究。如果您var_dump($attriubte),您会发现它不是NotNull 的实例,但很乐意提供帮助。
猜你喜欢
  • 2010-09-21
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
相关资源
最近更新 更多