Атрибути в Laravel: Що під капотом.

Теги в PHP, введені в версії 8.0, надають спосіб додавати метадані до класів, методів, властивостей і не тільки. У Laravel атрибути можуть бути використані для спрощення ін'єкції залежностей та зробити ваш код більш виразним.

  1. Реалізація «під капотом».

У Laravel атрибути, які використовуються для контекстного вирішення залежностей, повинні реалізовувати інтерфейс ContextualAttribute. Це забезпечує правильне вирішення залежностей через контейнер сервісів Laravel, коли ці атрибути застосовуються до параметрів. Хоча ContextualAttribute є порожнім інтерфейсом, вам потрібно реалізувати метод resolve, щоб обробляти логіку залежностей.

pic

В середині фреймворка перевіряється, чи реалізує атрибут інтерфейс ContextualAttribute, після чого викликається метод resolveFromAttribute.

pic

pic

Ви також можете зареєструвати зворотний виклик для конкретного атрибута, використовуючи метод whenHasAttribute. Цей метод дозволяє зареєструвати функцію, яка буде виконана, коли атрибут з конкретним класом буде знайдений під час процесу вирішення залежностей.

pic

Інший метод, який ви можете використати, називається after, який виконується після вирішення залежності. Метод after у атрибутах дозволяє виконувати певні дії або обробку даних після створення об'єкта. Ось декілька прикладів:

pic

Обробка даних
Атрибути можуть містити логіку, яка має виконуватися після ініціалізації об'єкта або виконання певних кроків. Наприклад, ви можете налаштувати зв'язки між об'єктами або обробити дані, які були встановлені в об'єкті.

Хуки після обробки
Метод after може виступати як хук, дозволяючи виконувати додаткову функціональність після основного процесу. Наприклад, він може обробляти логування.

Інтеграція контексту
Атрибути можуть включати контекстно-залежну логіку, а метод after дозволяє цій логіці взаємодіяти з об'єктом або системою.

Метод after приймає три параметри. Перший — це сам атрибут, другий — об'єкт, який був створений у методі resolve, і третій — контейнер.

Також, «під капотом», Laravel перевіряє, чи є зареєстровані зворотні виклики для заданого атрибута, і, якщо вони є, виконує їх.

pic

Зворотні виклики корисні, коли ви хочете виконати дії з уже існуючими атрибутами, наприклад, атрибутами з пакету або тими, які надає сам Laravel. Більше про це буде сказано нижче. Для цього потрібно викликати метод afterResolvingAttribute на контейнері і передати зворотний виклик. Параметри цього методу такі ж, як і в методі after.

pic

2) Розглянемо приклад, чому атрибути можуть бути корисними для вас.

Створимо кастомний атрибут Autowired, який дозволить автоматичну ін'єкцію залежностей на основі вказаного класу.

pic

Ось що відбувається в атрибуті Autowired:

  1. Оголошення атрибута: #[Attribute(Attribute::TARGET_PARAMETER)] вказує, що цей атрибут може бути застосований тільки до параметрів.
  2. Рішення залежності: Метод resolve використовує контейнер Laravel для вирішення класу, переданого в атрибут.
  3. Конструктор: Приймає ім'я класу залежності для ін'єкції.

Визначення репозиторію

Шаблон репозиторію відокремлює логіку доступу до даних від шару сервісів.
Ось інтерфейс та реалізація:

pic

pic

Далі, давайте використаємо атрибут Autowired, щоб ін'єктувати репозиторій у сервіс.

pic

Створюючи кастомний атрибут Autowired, ви можете оптимізувати ін'єкцію залежностей і зробити ваші Laravel-додатки більш виразними та підтримуваними. Замість того, щоб вручну вказувати зв'язки для репозиторіїв у сервіс-провайдері, ви можете використовувати атрибут #[Autowired], щоб автоматично ін'єктувати правильну реалізацію або конфігурацію безпосередньо там, де це потрібно. Це усуває необхідність у повторюваних викликах $this->app->when() для специфічної бізнес-логіки.

pic

3. Які атрибути вже існують.

#[Auth]

Атрибут #[Auth] забезпечує безшовну інтеграцію з системою аутентифікації Laravel і спрощує доступ до охоронця аутентифікації.

pic

#[Cache]

Атрибут #[Cache] полегшує роботу з механізмом кешування Laravel, автоматично вирішуючи екземпляри сховища кешу.

pic

#[Config]

Атрибут #[Config] спрощує доступ до конфігураційних значень Laravel, ін'єктуючи їх безпосередньо туди, де вони потрібні.

pic

#[CurrentUser]

Атрибут #[CurrentUser] дозволяє отримати поточного автентифікованого користувача коротким і елегантним способом.

pic

#[DB]

Ін'єктує конкретне підключення до бази даних.

pic

#[Log]

Атрибут #[Log] надає доступ до екземпляра логера.

pic

#[RouteParameter]

Атрибут #[RouteParameter] автоматично вирішує параметри маршруту, спрощуючи роботу з динамічними маршрутами.

pic

#[Storage]

Атрибут #[Storage] дозволяє працювати з системою зберігання Laravel.

pic

#[Tag]

Позначає сервіс для подальшого отримання.

pic

На завершення.

Атрибути Laravel надають потужний спосіб покращити та спростити ін'єкцію залежностей, обробку конфігурацій та інші основні функціональності у вашому додатку.

Мені було б цікаво почути вашу думку! Поділіться в коментарях, які атрибути ви хотіли б використовувати або побачити реалізованими.
Крім того, не соромтеся поділитися своїми ідеями щодо того, як ви плануєте використовувати методи, такі як after та afterResolvingAttribute. Ваші думки можуть надихнути на нові й захоплюючі варіанти використання!

Перекладено з: Attributes in Laravel Under the Hood.

Leave a Reply

Your email address will not be published. Required fields are marked *