Искал реализацию EAV (Entity-Attribute-Value) паттерна на PHP или Symfony и не нашел. Типичная задача, но, на удивление, нет таких библиотек. Решил сделать свою — EAV bundle (GitHub). Есть достаточно подробная документация.

Основные возможности:

  • Атрибуты могут иметь значения любого типа (single type) или перечисления (enum), определяемые пользователем. Они также могут быть одиночными или множественными.

  • Привязка атрибутов к одной или нескольким категориям или тегам. Например, вы хотите отображать определённые атрибуты товара только для одной или нескольких категорий товаров. Также можно включить атрибуты родительских категорий.

  • Один атрибут может быть связан с несколькими типами сущностей и тегов.

  • Конвертирование и инвертирование EAV в базу данных и из неё на стороне клиента. Внутренняя проверка входных данных.

  • Фабрика для создания запросов на фильтрацию сущностей по атрибутам с проверкой привязки тегов.

  • Слушатель, который проверяет изменённые теги, атрибуты, сущности и удаляет потерянные EAV из базы данных.

  • Готовый к использованию пользовательский интерфейс CRUD для EAV, основанный на Symfony Forms и интегрированный с EasyAdmin.

Было бы неплохо еще реализовать создание сущностей через MakerBundle, чтение опций из PHP атрибутов сущности, рефлексии и некоторые другие возможности.

Комментарии (5)


  1. SbWereWolf
    30.10.2025 21:11

    Плохо искал. Мои первые статьи на эту тему были опубликованы в 2017 году,последние в 2022: Идеальный каталог, пример использования https://habr.com/p/599639/

    Можно установить с помощью composer:

    composer require sbwerewolf/eav-manager

    Если на сайте https://packagist.org/ поискать "eav" или "eav ", то в результатах поиска будет не один десяток пакетов.

    Но после того как появиламь MongoDb, и особенно после того как в Postgre появилась поддержка JSON (тип данных jsonb), всё это потеряло актуальность.

    EAV имеет смысл только как способ генерации таблиц, но эта таблица теряет исторические данные, когда какое то свойство исключается из сущности. При хранении в JSONB ни чего не теряется, индексы для свойств JSON работают так же как для колонок таблицы, но нет лишних колонок, ч о более совместимо с современным способом разработки микросервисов.

    Твоя статья требует продолжения с use cases, без этого ни кто не начнет использование, даже ради эксперимента


    1. maxkain Автор
      30.10.2025 21:11

      Это вообще не то. Какие use cases, ты, видимо, документацию не открывал. Почему из-за JSONB теряется актуальность таблиц? Таблицы имеют преимущество из-за наличия схемы. Какие лишние колонки, о чем ты? При чем здесь, вообще, микросервисы...


  1. ideavi
    30.10.2025 21:11

    Да, похоже, вообще не искал, а использует сообщество как экспертную систему :-)
    Вот тебе пара ссылок, брат, бери сразу IDEAV, далеко пойдешь.

    https://habr.com/ru/companies/neoflex/articles/433058/
    https://habr.com/ru/articles/900308/
    Если интересно, дам и сам код ядра.


    1. ideavi
      30.10.2025 21:11

      Use case примерно такой, и это годится не только для программиста, но и для пытливого пользователя с архитектурным видением
      https://rutube.ru/video/c85b3e7e11dc9f96f0f091d308968126/


    1. maxkain Автор
      30.10.2025 21:11

      У тебя может сильно падать скорость выборки по EAV, если ты используешь JOIN + GROUP BY (или DISTINCT). Подзапросы (semi-joins) будут быстрее. И ты просто партицируешь таблицу, это, хорошо, конечно. Но уже существуют распределенные базы данных, как TiDB, что еще лучше. Там автоматический шардинг, репликации. А в TiDB еще есть и автоматическая репликация в колоночное хранилище, и СУБД сама определяет по характеру запроса откуда лучше делать выборку.