Атрибуты в php

PHP-атрибуты — структурированные машиночитаемые метаданные для классов, методов, функций, параметров, свойств и констант

    Атрибуты в php

    Прежде всего, пользовательские атрибуты - это простые классы, аннотируемые самим атрибутом #[Attribute]
    В отличие от интерфейсов, которые заставляют добавлять в класс обязательные методы, атрибуты аннотируют код и не требуют изменять структуру класса.
    Атрибуты инспектируют при выполнении кода через API-интерфейс модуля Reflection, добиваясь динамического поведения без изменения кода
    Метаданные, связанные с атрибутами, можно извлекать во время выполнения кода с помощью API модуля Reflection


    Некоторые возможности использования атрибутов:
    Валидация данных.
    Маршрутизация
    Обработка событий
    Ограничение области применения

    Атрибуты умеют дополнять класс методами, которые не требует интерфейс, или заменять интерфейсные методы только за счёт добавления метаданных, без изменения структуры интерфейса
    Пример добавления в класс дополнительных неинтерфейсных методов через атрибуты:

    interface ActionHandler { public function execute(); } #[Attribute] class SetUp {} class CopyFile implements ActionHandler { public string $fileName; public string $targetDirectory; public string $contents; #[SetUp] public function fileExists():void { if (file_exists($this->fileName)) { echo $this->fileName . ' already exists' . PHP_EOL; } } #[SetUp] public function targetDirectoryExists():void { if(file_exists($this->targetDirectory)) { echo "$this->targetDirectory exists.\n"; } } public function execute():void { file_put_contents($this->fileName, $this->contents); echo "File successfully written to {$this->fileName}. \n\n"; } } function executeAction(ActionHandler $actionHandler):void { $actionHandler->targetDirectoryExists(); $actionHandler->fileExists(); $actionHandler->execute(); $reflection = new ReflectionObject($actionHandler); #var_dump($reflection->getFileName()); #var_dump($reflection->getInterfaceNames()); #var_dump($reflection->getMethods()); #var_dump($reflection->getProperties()); var_dump($reflection->getProperty('fileName')->getValue($actionHandler)); foreach ($reflection->getMethods() as $method) { $attributes = $method->getAttributes(SetUp::class); if (count($attributes) > 0) { $methodName = $method->getName(); $actionHandler->$methodName(); } } $actionHandler->execute(); } $copyAction = new CopyFile(); $copyAction->fileName = "test.txt"; $copyAction->targetDirectory = "folder"; $copyAction->contents = "test123"; executeAction($copyAction);
    Синтаксис атрибутов

    Синтаксис атрибута состоит из следующих компонентов: объявление атрибута начинается с символов #[ и заканчивается символом ], внутри которых через запятую перечисляют названия атрибутов. Название атрибута указывают как относительное, полное или абсолютное, как описывает раздел «Основы пространств имён»
    Аргументы атрибута необязательны и указываются в круглых скобках ()


    При запросе экземпляра атрибута через API-интерфейс модуля Reflection название атрибута разрешается в название класса, а аргументы атрибута передаются в конструктор этого класса. Поэтому для каждого атрибута определяют отдельный класс.

    // a.php namespace MyExample; use Attribute; #[Attribute] class MyAttribute { const VALUE = 'value'; private $value; public function __construct($value = null) { $this->value = $value; } } // b.php namespace Another; use MyExample\MyAttribute; #[MyAttribute] #[\MyExample\MyAttribute] #[MyAttribute(1234)] #[MyAttribute(value: 1234)] #[MyAttribute(MyAttribute::VALUE)] #[MyAttribute(array("key" => "value"))] #[MyAttribute(100 + 200)] class Thing {} #[MyAttribute(1234), MyAttribute(5678)] class AnotherThing {}

    Чтение атрибутов через API-интерфейс модуля Reflection

    Для доступа к атрибутам классов, методов, функций, параметров, свойств и констант класса в API-интерфейсе модуля Reflection предусмотрели метод getAttributes().
    Метод возвращает массив объектов ReflectionAttribute, каждый из которых умеет возвращать название и аргументы атрибута, и создавать объект класса, которым представили атрибут.

    #[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));
    Передача параметров атрибутам

    В атрибуты можно передавать параметры, чтобы они могли быть прочитаны кодом, использующим их

    ... #[User('permissions')] public function access() ...
    Модуль интроспекции кода Reflection

    PHP поставляется с полным API рефлексии, который открывает доступ к интроспекции классов, интерфейсов, функций, методов и модулей. API модуля Reflection умеет извлекать doc-блоки комментариев к функциям, классам и методам.


    https://www.php.net/manual/ru/book.reflection.php

    #Пример использования Reflection из shell (терминала) php --rf strlen php --re json
    Расширение

    Если вам нужна специализированная версия встроенного класса (который, например, сможет генерировать цветной HTML при экспорте, будет иметь легкодоступные свойства вместо методов или же какие-нибудь вспомогательные методы), то можете просто взять и расширить его.

    class My_Reflection_Method extends ReflectionMethod


    Источник: https://www.php.net/manual/ru/reflection.extending.php


    Источники
    Последнее изменение: 23.05.2026 10:12


    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ