Ответ
Атрибуты (Attributes) — это форма структурных метаданных, добавленная в PHP 8.0. Они позволяют добавлять декларативную информацию к классам, методам, свойствам, параметрам функций и другим сущностям кода. Эта информация затем может быть прочитана во время выполнения с помощью Reflection API и использована для различных целей: маршрутизации, валидации, конфигурации ORM и т.д.
Ключевые особенности:
- Объявляются с помощью синтаксиса
#[...]. - Могут иметь параметры, передаваемые в конструктор.
- Могут быть ограничены определёнными типами сущностей (только классы, только методы и т.п.).
Пример создания и использования атрибута для маршрутизации:
<?php
// 1. Объявляем собственный атрибут
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Route
{
public function __construct(
public string $path,
public string $method = 'GET'
) {}
}
// 2. Применяем атрибут к классу и методу
#[Route('/api/user')]
class UserController
{
#[Route('/profile', 'GET')]
public function getProfile(): array
{
return ['name' => 'John'];
}
#[Route('/update', 'POST')]
public function updateProfile(): void {}
}
// 3. Чтение атрибутов через Reflection
$reflectionClass = new ReflectionClass(UserController::class);
$classRoute = $reflectionClass->getAttributes(Route::class)[0] ?? null;
if ($classRoute) {
$routeInstance = $classRoute->newInstance();
echo 'Базовый путь контроллера: ' . $routeInstance->path; // Выведет: /api/user
}
$reflectionMethod = new ReflectionMethod(UserController::class, 'getProfile');
$methodRoute = $reflectionMethod->getAttributes(Route::class)[0]->newInstance();
echo 'Метод запроса: ' . $methodRoute->method; // Выведет: GET
Практическое применение: Современные PHP-фреймворки (Symfony, Laravel 8+) активно используют атрибуты вместо аннотаций в док-блоках для конфигурации маршрутов, валидации полей (#[AssertEmail]), описания сущностей Doctrine ORM (#[ORMEntity]) и регистрации слушателей событий.