PHP 8 属性:是否可以验证传递给属性的元数据或强制属性实例化?

PHP 8 Attributes: Is it possible to validate metadata passed to attributes or force attribute instantiation?

稍微玩一下新的 PHP 8 个属性(注释)(https://stitcher.io/blog/attributes-in-php-8) 我开始创建自己的属性。

简单示例:

namespace CisTools\Attribute;

use Attribute;
use CisTools\Exception\BadAttributeMetadataException;

/**
 * For defining a description.
 */
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class Description
{
    /**
     * @param string $description
     * @throws BadAttributeMetadataException
     */
    public function __construct(string $description)
    {
        if (strlen($description) < 10) {
            throw new BadAttributeMetadataException("This is description is too short.");
        }
    }
}

希望下面的代码会抛出一个 BadAttributeMetadataException 不幸的是它成功完成了:

use CisTools\Attribute\Description;

#[Description("quack")]
class Test {

    public function __construct() {
        echo "hello world";
    }

}

new Test();

是否可以验证为(自定义)属性传递的元数据?很可能必须以某种方式自动实例化属性。

不知道你到底想要什么

但检查这个我认为可以帮助你 "get_meta_tags(string $filename, bool $use_include_path = false): array|false"

https://www.php.net/manual/en/function.get-meta-tags.php

一切皆有可能——截至今天,我已经针对这个问题实施了一个可行的解决方案,它可以很好地用于图书馆(以防万一有人也需要):

function cis_shutdown_validate_attributes()
{
    if(!defined('CIS_DISABLE_ATTRIBUTE_VALIDATION')) {
        foreach(get_declared_classes() as $class) {
            try {
                $reflection = new ReflectionClass($class);
            } catch (\Throwable $throwable) {
                continue;
            }
            $attributes = $reflection->getAttributes();
    
            foreach ($attributes as $attribute) {
                $attribute->newInstance();
            }
        }
    }
}

register_shutdown_function('cis_shutdown_validate_attributes');

(您也可以自动加载它:Composer/PSR - How to autoload functions?