Что такое атрибуты в PHP?

«Что такое атрибуты в PHP?» — вопрос из категории PHP Core, который задают на 28% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Атрибуты (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]) и регистрации слушателей событий.