Reading Attributes with the Reflection API

Оновлено: 09.05.2023

Для доступу до атрибутів класів, методів, функцій, параметрів, властивостей та констант класу Reflection API надає метод getAttributes() для кожного з відповідних об'єктів Reflection. Цей метод повертає масив екземплярів ReflectionAttribute, які можна запитувати для отримання імені атрибута, аргументів та для створення екземпляра представленого атрибута.

Таке відокремлення відображеного представлення атрибута від фактичного екземпляра збільшує контроль програміста над помилками, пов'язаними з відсутніми класами атрибутів, неправильно введеними або відсутніми аргументами. Тільки після виклику ReflectionAttribute::newInstance() відбувається інстанціювання об'єктів класу атрибута і перевірка правильності відповідності аргументів, не раніше.

Приклад #1 Читання атрибутів з використанням Reflection API

<?php

#[Attribute]
class MyAttribute
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }
}

#[MyAttribute(value: 1234)]
class Thing
{
}

function dumpAttributeData($reflection) {
    $attributes = $reflection->getAttributes();

    foreach ($attributes as $attribute) {
       var_dump($attribute->getName());
       var_dump($attribute->getArguments());
       var_dump($attribute->newInstance());
    }
}

dumpAttributeData(new ReflectionClass(Thing::class));
/*
string(11) "MyAttribute"
array(1) {
  ["value"]=>
  int(1234)
}
object(MyAttribute)#3 (1) {
  ["value"]=>
  int(1234)
}
*/

Замість того, щоб перебирати всі атрибути в екземплярі відображення, можна отримати лише ті, що належать до певного класу атрибутів, передавши ім'я шуканого класу атрибутів як аргумент.

Приклад #2 Читання специфічних атрибутів з використанням Reflection API

<?php

function dumpMyAttributeData($reflection) {
    $attributes = $reflection->getAttributes(MyAttribute::class);

    foreach ($attributes as $attribute) {
       var_dump($attribute->getName());
       var_dump($attribute->getArguments());
       var_dump($attribute->newInstance());
    }
}

dumpMyAttributeData(new ReflectionClass(Thing::class));