PHP: Атрибуты для добавления метаданных

Атрибуты, введённые в PHP 8, представляют собой способ добавления метаданных к классам, методам, функциям, параметрам, свойствам и т.д. в виде аннотаций, что делает код более читаемым и позволяет избегать использования документационных комментариев для этих целей. Атрибуты можно использовать для самых разных задач, например, для указания конфигураций роутинга в веб-приложениях, валидации данных или кэширования.

В PHP атрибуты объявляются через двойные квадратные скобки #[AttributeName]. Вот пример использования атрибута:

#[Attribute]
class MyAttribute
{
    public function __construct( public string $value )
    {
    }
}

#[MyAttribute(value: "Пример использования атрибута")]
class MyClass
{
}

Получить информацию об атрибутах можно с помощью Отражений (Reflection API):

$reflectionClass = new ReflectionClass( MyClass::class );
$attributes = $reflectionClass->getAttributes();

foreach( $attributes as $attribute )
{
    $instance = $attribute->newInstance();
	var_dump( $instance );
	#> object(MyAttribute)#3 (1) { ["value"]=> string(56) "Пример использования атрибута" }
    echo $instance->value;
	#> Пример использования атрибута
}

Расширенный пример с пространством имён и получением атрибута метода класса

namespace MyExampleNamespace;

use Attribute;
use ReflectionClass;
use ReflectionMethod;

#[Attribute]
class MyAttribute
{
    public function __construct(public string $value)
    {
    }
}

#[Attribute]
class MethodAttribute
{
    public function __construct(public string $description)
    {
    }
}

#[MyAttribute(value: "Пример использования атрибута с namespace")]
class MyClass
{
    #[MethodAttribute(description: "Пример атрибута для метода")]
    public function myMethod()
    {
        return "Метод с атрибутом";
    }
}

# Получаем информацию об атрибутах класса
$reflectionClass = new ReflectionClass( MyClass::class );
$classAttributes = $reflectionClass->getAttributes();

foreach( $classAttributes as $attribute )
{
    $instance = $attribute->newInstance();
    echo "Класс атрибут: " . $instance->value . "\n";
}


# Получаем информацию об атрибутах метода
$reflectionMethod = new ReflectionMethod( MyClass::class, 'myMethod' );
$methodAttributes = $reflectionMethod->getAttributes();

foreach( $methodAttributes as $attribute )
{
    $instance = $attribute->newInstance();
    echo "Метод атрибут: " . $instance->description . "\n";
}

Расширенный пример, где класс атрибута содержит свой метод, константу и аргумент

namespace MyExampleNamespace;

use Attribute;
use ReflectionClass;
use ReflectionMethod;

#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class MyAttribute
{
	const EXAMPLE_CONSTANT = 'Пример константы';

	public function __construct( public string $value )
	{
	}

	public function customMethod(): string
	{
		return "Значение аргумента: {$this->value}, константа: " . self::EXAMPLE_CONSTANT;
	}
}

#[MyAttribute(value: "Пример использования атрибута с namespace для класса")]
class MyClass
{
	#[MyAttribute(value: "Пример использования атрибута для метода")]
	public function myMethod()
	{
		# Тело метода
	}
}

# Получаем информацию об атрибутах класса
$reflectionClass = new ReflectionClass( MyClass::class );
$classAttributes = $reflectionClass->getAttributes();

foreach( $classAttributes as $attribute )
{
	$instance = $attribute->newInstance();
	echo $instance->customMethod() . PHP_EOL;
}

# Получаем информацию об атрибутах метода
$reflectionMethod = new ReflectionMethod( MyClass::class, 'myMethod' );
$methodAttributes = $reflectionMethod->getAttributes();

foreach( $methodAttributes as $attribute )
{
	$instance = $attribute->newInstance();
	echo $instance->customMethod() . PHP_EOL;
}
PHP Просмотров: 218
Оценить код:

Комментарии

Ваш комментарий будет первым.
Войдите, чтобы оставить комментарий.