首页 > 解决方案 > 是否可以使用 PHP 8 属性实现接口并检查它是否是该接口的实例?

问题描述

我有一个 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
        }
    }
}

标签: phpreflectionphp-8

解决方案


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

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

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


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

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

3v4l.org上查看此工作


推荐阅读