Skip to content

Feature Tags

github-actions[bot] edited this page Jul 8, 2026 · 1 revision

🏷️ Теги и tagged services

← Возможности · Главная · Сравнение

Группировка сервисов по метке: tag($id, $tag, $priority = 0) → получить всю группу как массив, ленивый итератор или локатор, упорядоченную по приоритету. Туториал — Tags-and-decorators.

Принцип работы

tag() добавляет id в список тега с необязательным приоритетом (больше — раньше; при равном приоритете сохраняется порядок регистрации, стабильно). Получить группу можно несколькими способами — все отдают элементы в порядке приоритета:

  • getTagged($tag) — массив разрешённых экземпляров (ключи — id сервисов; создаёт все сразу);
  • getTaggedIterator($tag)ленивый итератор (создаёт по мере обхода);
  • getTaggedLocator($tag) — PSR-11-локатор по группе (создаёт по требованию, по id);
  • getTaggedIds($tag) — только id, без создания.
$c->tag(SmsNotifier::class, 'notifiers', 10);   // выше приоритет — раньше в группе
$c->tag(EmailNotifier::class, 'notifiers');      // приоритет 0

foreach ($c->getTaggedIterator('notifiers') as $notifier) {
    $notifier->send($message); // сначала SmsNotifier (10), затем EmailNotifier (0)
}

В конфигурации приоритет задаётся записью ['id' => ..., 'priority' => N] в секции tags (строковая форма 'id' — приоритет 0). Коллекция getTagged() индексируется по id сервиса.

Плюсы

  • Расширяемость через плагины: новый сервис + тег — и он автоматически в группе, без правок потребителя.
  • Ленивые итератор/локатор не создают неиспользуемые сервисы.
  • Идеально для наборов: подписчики событий, нотификаторы, валидаторы, middleware.

Минусы

  • Порядок в группе нужно контролировать явно, если он важен.
  • «Неявная» связь: по коду потребителя не видно, кто в теге (смотрите dump()).

✅ Рекомендуется

  • Для больших групп — getTaggedIterator() / getTaggedLocator() (ленивость), а не getTagged().
  • Сочетать со сканированием: сканируем каталог хендлеров → тегируем → собираем.

❌ Антипаттерны

  • getTagged() (создаёт всё сразу) для большого тега, из которого нужен один сервис.
  • Зашивать порядок обработки в порядок регистрации без явной сортировки/приоритета.

Аналоги в других контейнерах

Контейнер Аналог
PHP-DI нет нативных тегов (⚠️ — через фабрику-коллекцию)
Symfony tags: + !tagged_iterator / tagged locator (эталон)
Laravel tag() + tagged() (⚠️ без ленивого локатора)
Pimple нет (❌)
Nette tags в конфиге + findByTag

CloudCastle, PHP-DI, Symfony, Nette — CloudCastle даёт массив + ленивый итератор + локатор.

См. также: Tags-and-decorators (гайд) · Сканирование каталога.

Clone this wiki locally