Что это такое атрибуты в PHP 8
Сама концепция атрибутов уже давно известна, мы много лет используем аннотации (докблоки) для добавления каких-то метаданных к классам, свойствам, методам, переменным и т.д. Думаю всем давно известны примеры из PHPUnit, Doctrine ORM, Assert и многих других либок и фреймворков.
Как это работало раньше?
В PHP докблоки «рефлексивны»: к ним можно получить доступ с помощью метода API Reflection getDocComment() на уровне функции, класса, метода и атрибута. Сначала нужно было получить комментарии класса и метода(ов), затем с помощью регулярных выражений распарсить необходимые аннотации. Код выглядел примерно так
$ref = new ReflectionClass(CopyFile::Class); //получаем комментарии к классу $methodComments = $ref->getMethod('someAction')->getDocComment(); print $methodComments; //регулярное выражение для получения аннотации //в зависимости от вашего типа аннотации оно может отличаться $pattern = "##"; //получаем все аннотации для классаpreg_match_all($pattern, $methodComments, $matches); print_r($matches);Как это работает сейчас и в чём разница?
Атрибуты дают фактически те-же возможности, однако этот способ конфигурации встроен непосредственно в язык, что даёт преимущество в скорости и читабельности. Если раньше некоторые не использовали аннотации, аргументируя это тем, что аннотации - по сути комментарии и не могут быть кодом для выполнения, а так же, функционал, который их использует, сложно распространять, то сейчас это часть языка. Вот так это может выглядеть теперь
$reflection = new ReflectionClass(CopyFile::Class); $attributes = $reflection->getAttributes(); //или для методов foreach ($reflection->getMethods() as $method){ $attributes = $method->getAttributes(SomeAttribute::Class); // выбираем конретный атрибут if (count($attributes) > 0) { $methodName = $method->getName(); $actionHandler->$methodName(); } }Также можно (а согласно документации даже очень нужно) создавать классы атрибутов для этого нужно использовать атрибут #[Attribute], который можно импортировать из глобального пространства имён
use Attribute; #[Attribute] class MyAttribute{ }с помощью оператора use. Они могут быть пустыми, но так-же могут содержать дополнительную информацию
#[Attribute] class MyAttribute{ public $value; public function __construct($value){ $this->$value = $value; } } #[MyAttribute](value: 123) class Thing{ }, в виде параметров которые также легко можно прочитать:
$attributes = $reflection->getAttributes(MyAttribute::class); foreach ($attributes as $attribute) { $attribute->getArguments(); }Как вы поняли из примера, параметры будут переданы в конструктор класса MyAttribute. Параметры могут быть простыми скалярными типами, массивами, константами и т.д.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.