PHP workshop for 2 days with Shopware, Sylius, PHPUnit and Codeception in Duisburg

Чтение атрибутов с помощью Reflection API

Для доступа к атрибутам классов, методов, функций, параметров, свойств и констант класса, в Reflection API присутствует метод getAttributes() для каждого из перечисленных объектов рефлексии. Этот метод возвращает массив экземпляров 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));
add a note add a note

User Contributed Notes 1 note

up
2
Hirusha Sharma
7 months ago
Fetch properties from functions:

----------------------------------------
Function definition with attributes:
----------------------------------------
#[ReadOnly]
#[Property(type: 'function', name: 'Hello')]
function Hello()
{
    return "Hello";
}

-----------------------------------------
Gather attributes from the function
-----------------------------------------
function getAttributes(Reflector $reflection)
{
    $attributes = $reflection->getAttributes();
    $result = [];
    foreach ($attributes as $attribute)
    {
        $result[$attribute->getName()] = $attribute->getArguments();
    }
    return $result;
}

$reflection = new ReflectionFunction("Hello");
print_r(getAttributes($reflection));

-----------------------------
OUTPUT
-----------------------------
Array
(
    [ReadOnly] => Array
        (
        )

    [Property] => Array
        (
            [type] => function
            [name] => Hello
        )

)
To Top