Кастомные таблицы в MODX: когда нужен xPDO, а когда нет
Для таблицы заказов, подписок или журнала событий в MODX можно описать xPDO-модель, обращаться к базе через PDO или расширить стандартные объекты. Выбор влияет не только на объём кода, но и на обновления, поддержку и риск ошибок в запросах.

Для таблицы заказов в MODX есть три рабочих пути: описать модель xPDO, выполнять запросы через PDO или встроить данные в стандартные объекты MODX. Первый подход даёт интеграцию с экосистемой CMS, второй оставляет больше контроля над SQL, третий подходит, только если данные действительно совпадают по смыслу с существующей сущностью. Ошибка выбора оборачивается либо лишней инфраструктурой, либо кодом, который трудно поддерживать после обновления проекта.
Сначала проверьте: вам точно нужна отдельная таблица?
Если запись — это документ, ресурс или пользователь MODX, сначала проверьте, покрывают ли задачу стандартные таблицы и механизмы расширения. Например, создавать собственную таблицу документов, а затем вручную повторять работу с правами, публикацией и контекстами — обычно плохая сделка. Вы получаете второй каталог сущностей и сами отвечаете за поведение, которое MODX уже реализует.
Отдельная таблица оправдана, когда данные имеют собственную структуру и жизненный цикл: внешние идентификаторы заказов, события интеграции, технические логи. Не складывайте такие записи в поле ресурса только потому, что оно уже есть: поиск и обновление отдельных записей быстро превращаются в ручную работу.
Выбирайте не способ записать строку в базу, а способ, который команда сможет безопасно менять и проверять через полгода.
Три подхода и цена каждого
| Подход | Что получаете | За что платите | Когда выбирать |
|---|---|---|---|
| xPDO-модель | Объекты, единый слой доступа, связь с механизмами MODX | Нужно описать схему и поддерживать модель | Таблица — часть постоянной функциональности компонента |
| PDO и SQL | Прямой контроль над запросами и схемой | Связи, преобразование данных и часть проверок пишете сами | Сложный запрос или разовая интеграция без полноценной модели |
| Стандартная сущность MODX | Повторное использование готового поведения | Нужно подчиниться структуре и правилам этой сущности | Данные по смыслу действительно являются ресурсом, пользователем или другой сущностью CMS |
Модель xPDO1 — описание таблицы и её связей, по которому слой xPDO может работать с записями как с объектами. Это не просто класс с удобными методами: описание схемы становится частью поддержки компонента.
Когда оправдана модель xPDO
Берите xPDO, если таблица будет участвовать в обычной работе компонента: записи создаются и читаются из разных участков кода, есть связи с другими таблицами, нужны выборки по критериям, проект уже использует xPDO. Вы платите за начальную настройку схемы и генерацию или поддержку классов, зато не размазываете имя таблицы и правила преобразования данных по шаблонам и сниппетам.
Перед внедрением зафиксируйте структуру: первичный ключ, типы полей, обязательность значений, индексы и внешние связи. Затем проверьте, что схема соответствует реальной базе и что установщик компонента создаёт таблицу на чистой установке. Если при обновлении меняется структура, обновление должно менять её контролируемо — не рассчитывайте, что ручное редактирование базы повторят на каждом окружении.
Для новой реализации ориентируйтесь на версии вашего проекта: в MODX 2.x используется линия xPDO 2, а в MODX 3.x — xPDO 3. Не переносите классы, пространства имён и примеры конфигурации из одной линии в другую без сверки с документацией именно этой версии. Саму схему и способ подключения пакета также проверяйте по версии установленного xPDO.
Когда достаточно PDO и SQL
Прямой SQL разумен, если запрос узкий и специфичный: например, агрегат для отчёта или операция, которую неудобно выражать объектной моделью. Но PDO не снимает с вас ответственность за параметры и транзакции. Значения пользователя передавайте параметрами подготовленного запроса, а не склеивайте из строк. Имена таблиц и столбцов обычно нельзя безопасно подставить тем же способом, что значения: их выбирают из фиксированного списка, а не принимают из формы.
Если запрос выполняется через соединение MODX, приложение сохраняет общий контекст подключения. При использовании отдельного PDO-соединения появятся отдельные настройки, обработка ошибок и потенциально другая транзакция. Не смешивайте два соединения в операции, которая должна быть атомарной: откат одного не отменит запись, уже сделанную через другое.
SQL-код тоже должен иметь владельца. Договоритесь, где лежат запросы, как проверяются изменения схемы и как тестируются пустой результат, дубликаты и ошибки соединения. Иначе «быстрый запрос» становится скрытым API, о котором знает только автор.
Когда расширять стандартную сущность
Этот путь подходит, когда данные действительно описывают существующий объект MODX, а не просто связаны с ним. Например, дополнительная характеристика ресурса — кандидат на механизм расширения ресурсов; отдельная очередь отправки писем — нет. Во втором случае искусственное прикрепление очереди к ресурсам создаст зависимость от логики, которой очередь не должна подчиняться.
Перед расширением проверьте, как поле хранится, выводится и индексируется, кто имеет к нему доступ и что произойдёт при переносе сайта. Добавление поля к существующей сущности может упростить интерфейс, но усложнить миграции и выборки. Не меняйте ядро MODX ради такого расширения: обновление способно затереть правки.
Как выбрать без архитектурного проекта на месяц
- Опишите сущность. Перечислите поля, связи и срок жизни записи. Если это полноценный объект компонента, рассматривайте xPDO; если только отчётная выборка — SQL может быть проще. Проверка: в описании нет полей, смысл которых приходится объяснять через «почти ресурс».
- Проверьте встроенную модель. Убедитесь, что существующая сущность MODX не покрывает задачу без дублирования. Проверка: вы можете назвать конкретное стандартное поведение, которое хотите повторно использовать, а не просто факт, что таблица уже есть.
- Сверьте версии. Зафиксируйте версию MODX и xPDO в проекте, затем сверяйте примеры и документацию с ними. Проверка: выбранный способ подключения модели и её классы относятся к установленной линии xPDO.
- Продумайте установку и обновление. Проверьте создание таблицы на чистой базе и переход со старой схемы. Проверка: компонент устанавливается и обновляется без ручного изменения базы.
- Прогоните ошибки и нагрузочные места. Проверьте пустую таблицу, повторную запись, отсутствие связанной записи и запросы по типовым фильтрам. Проверка: ожидаемые ошибки обработаны, а план запроса использует нужные индексы.
Что ломается чаще всего
- Модель существует только на рабочем сервере. Разработчик создал таблицу вручную, но не добавил её создание в установщик компонента. На тестовом окружении функциональность падает.
- Схема и код разъехались. Поле переименовали в базе, но старый код продолжает его читать. Храните изменение схемы вместе с версией компонента и проверяйте обновление на копии старой базы.
- SQL собирают из пользовательского ввода. Параметризация защищает значения, но не превращает произвольные имена столбцов в безопасные. Для сортировки и фильтров используйте явное сопоставление допустимых вариантов.
- Запрос возвращает слишком много строк. Отчёт, который работал на десятке записей, начинает нагружать базу после роста таблицы. Добавьте подходящие индексы и измерьте запрос на объёме, близком к ожидаемому.
- Смешаны версии примеров. Код для xPDO 2 копируют в проект на MODX 3 без адаптации. Сначала сверяйте API и структуру модели с документацией установленной версии, а не с первым найденным сниппетом.
Что измерить после выбора
Универсального числа, после которого PDO становится быстрее xPDO, нет: результат зависит от запроса, схемы, индексов, объёма данных и способа загрузки объектов. Сравнивайте одинаковую операцию на одной базе: время выполнения, число обращений к базе, количество возвращённых строк и потребление памяти. Отдельно проверьте холодный и повторный вызов, если в приложении участвует кеширование.
Сначала настройте схему и индексы, затем измеряйте запросы на реалистичных данных. Если узкое место — отчётный SQL, переписывание всей модели на другой способ доступа редко решает проблему. Если же разные части компонента по-разному создают и обновляют одни записи, унифицируйте слой доступа до того, как расхождения появятся в продакшене.
Что делать дальше
Зафиксируйте версию MODX и xPDO, нарисуйте схему таблицы и решите, кто отвечает за её создание и обновление. Затем реализуйте один сценарий чтения и записи и проверьте его на чистой установке и на копии существующей базы. Для xPDO сверяйте синтаксис и структуру модели с документацией своей версии; инвалидация кеша и проектирование миграций — отдельные темы.
1 Схема — формальное описание таблиц, столбцов, типов данных и связей между ними; это не сама база, а её модель.
Редактор изображений: Убрать лишнее, заменить фон, добавить объект, расширить кадр — на вашем изображении.
Спросить за 20 ₽Источники: Официальная документация MODX по xPDO, Репозиторий xPDO
Частые вопросы
Можно ли использовать xPDO только для одной кастомной таблицы?
Нужно ли выбирать xPDO вместо PDO ради безопасности?
Подойдёт ли пример для MODX 3, если проект на MODX 2?
Можно ли хранить собственные данные в таблице ресурсов MODX?
Что проверить перед публикацией компонента?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.