Jump to main content Jump to doc navigation

Что такое @SELECT привязка?

Привязка @SELECT вызывает запрос к базе данных на основе предоставленного значения и возвращает результат.

Синтаксис

@SELECT `pagetitle` AS `name`,`id` FROM `[[+PREFIX]]site_content` WHERE `published` = 1 AND `deleted` = 0

Чтобы написать один из них, вы должны быть знакомы с MySQL синтаксисом. Рекомендуется сначала написать функциональный оператор MySQL, который выполняется без ошибок в командной строке MySQL (см. Ошибки ниже для некоторых ошибок). Убедившись, что ваш запрос работает, вы можете создать с ним привязку @SELECT.

Все, что вам нужно сделать, это после того, как вы получили рабочий запрос MySQL:

  • добавьте символ «@» перед вашим SELECT
  • пропустите заключительную точку с запятой и любые комментарии
  • поставить запрос в одну строку (без возврата!)

Вы можете разместить эту привязку в одном из двух мест:

  • На странице (отредактируйте страницу в менеджере). Страница, на которую вы хотите поместить эту привязку, должна использовать допустимый шаблон, и с этим шаблоном должны быть связаны правильные переменные шаблона. Если вы создали Переменную шаблона и связали ее с Шаблоном, и страница, над которой вы работаете, использует этот Шаблон, тогда у вас будет место для ввода текста для этой переменной при редактировании страницы. Вставьте туда "@SELECT ...". Это звучит сложнее, чем есть на самом деле, но этот раздел написан многословно для ясной документации.
  • Вы также можете поместить запрос в поле «Значение по умолчанию» для переменной шаблона. Если вы замените текст по умолчанию для переменной шаблона, которая уже используется, будьте осторожны, поскольку ваши страницы могут требовать определенного типа вывода, например, тип вывода, который возвращает привязка @SELECT.

ПОМНИТЕ: запрос должен быть на ОДНОЙ СТРОКЕ. Нет возврата!

Вам нужно будет выбрать только 2 столбца - первый - отображаемое значение, второй - значение каждой строки (входное значение).

Например, чтобы получить список активных пользователей в окне SELECT:

@SELECT `username` AS `name`,`id` FROM `[[+PREFIX]]users` WHERE `active` = 1

Альтернативы

Прежде чем мы усложним, рассмотрим это по-другому. Сниппет может сделать работу легче, чем связывание.

Если ваш запрос должен работать с переменными шаблона и вам требуется специальное форматирование для вывода, привязка @SELECT, вероятно, не подходит. Практически все, что делается с привязками, также возможно с Сниппетами, привязки просто обеспечивают ярлык. Когда вы начинаете чрезмерно использовать ярлык, вы можете столкнуться с головной болью.

Наличие пустой Опции

Выборочные запросы - отличный способ включить раскрывающийся список, но поскольку они ВСЕГДА возвращают результаты, может быть проблематично, если вы хотите, чтобы в раскрывающемся списке была пустая опция? Мы можем положиться на функцию «UNION ALL» MySQL для достижения этой цели.

Рассмотрим следующий запрос:

@SELECT '-none-' AS username, 0 AS id UNION ALL
SELECT `username`,`id` FROM `[[+PREFIX]]users` WHERE `active` = 1 ORDER BY username ASC

Просто имейте в виду, что порядок сортировки здесь может заставить ваш пустой параметр где-то в стеке, вместо того, чтобы держать его сверху. В приведенном выше примере в имени пользователя используется дефис, чтобы обеспечить его сортировку в верхней части списка.

Более сложный пример: переменные шаблона

Что если вам нужно написать запрос, который обращается к переменным шаблона, связанным с конкретной страницей? Эти переменные не хранятся непосредственно в таблице site_content, они хранятся в других таблицах. Это заставляет вас писать оператор JOIN. Вот более осязаемый пример: допустим, что все страницы в определенной папке имеют переменную шаблона для opening_date ... этого поля нет в таблице "site_content". Держитесь за задницу, потому что это становится сложным.

Вы должны смотреть на кровавую сантехнику MODX, чтобы осуществить это. Вы должны понимать, как MODX расширяет данные, хранящиеся в таблице «site_content», и использует настраиваемые поля, известные как «переменные шаблона». Это открыто для некоторых дискуссий, но, к сожалению, схема базы данных MODX не соответствует строгим рекомендациям для внешних ключей ... не всегда ясно, на какую таблицу ссылается конкретный столбец ... даже не всегда ясно, что столбец "является" внешним ключом, но будьте уверены, это возможно ... требуется лишь немного терпения, чтобы выяснить это.

Во-первых, взгляните на следующие таблицы (у вас могут быть префиксы к именам таблиц):

  • site_templates - содержит фактический код шаблона, используемый для сайта (в поле содержимого отображается много HTML-кода).
  • site_tmplvars - содержит имя переменной шаблона. Поле «имя» - это то, что вызывает замену. Например. Имя "my_template_variable" следует использовать как [[*my_templat_variable]]. Если вы задумаетесь об этом архитектурно, эта таблица определяет класс переменных: имя и тип переменной, которая будет иметь ряд страниц.
  • site_tmplvar_contentvalues - содержит значения переменных шаблона для каждой страницы, которая их использует. Таблица базы данных имеет 4 поля: id, tmplvarid (внешний ключ назад к site_tmplvars.id), contentid (внешний ключ назад к site_content.id), value (a text field). Архитектурно, эта таблица представляет instances определенного класса. Другими словами, один ряд в site_tmplvars таблица может иметь несколько строк в этой таблице (по одной строке для каждого экземпляра переменной).
  • site_tmplvar_templates - Это таблица сопоставления, которая связывает переменную шаблона с шаблоном (maps site_template:id для site_tmplvars:id). Содержит 3 поля: tmplvarid, templateid, rank.

В нашем примере мы хотим фильтровать на основе настраиваемого поля даты с именем "opening_date", но если вы посмотрите внимательно, то site_tmplvar_contentvalues.value поле является text полем. MySQL не будет автоматически распознавать произвольный текст как значение даты, поэтому вам придется использовать MySQL функцию str_to_date(). Вы можете подумать, что site_tmplvars.display_params здесь спаситель, но это не так ... вы в конечном итоге разбиваете нос прямо в грязную истину о том, что форматы, используемые PHP strftime() (хранящуюся в site_tmplvars.display_params) не совпадают с тем, что MySQL может использовать в своей функции STR_TO_DATE(). Может быть способ автоматически сделать это, но проще просто жестко закодировать его. Вы можете получить такой запрос:

SELECT
        page.alias,
        tv_val.value,
        DATE_FORMAT(STR_TO_DATE(tv_val.value, '%d-%m-%Y %H:%i:%s'), '%Y-%m-%d %H:%i:%s') as `Formatted Opening Date`,

FROM site_content as page
JOIN site_tmplvar_contentvalues as tv_val ON page.id=tv_val.id
WHERE
        page.parent='95'
        AND tv_val.tmplvarid='6' /* 6 is the opening_date */
        AND DATE_FORMAT(STR_TO_DATE(tv_val.value, '%d-%m-%Y %H:%i:%s'), '%Y-%m-%d %H:%i:%s')>'2008-10-24 13:04:57'
;

MODX использует механизм таблиц MyISAM, а не InnoDB, поэтому он не обеспечивает жесткое применение ограничений внешнего ключа, которые определяются структурой таблицы.

ОШИБКИ

Что если ваш оператор MySQL выполняется отлично, но как только вы поместите его в привязку SELECT, он потерпит неудачу? Ну, есть некоторые ямы. Реализация не идеальна. Обратите особое внимание на следующее:

  • Ваш запрос ДОЛЖЕН отображаться в одной строке. Символы новой строки приводят к засорению привязки @SELECT.
  • Удалить все комментарии MySQL /* this style */ и - этот стиль
  • Убедитесь, что вы правильно ввели имена таблиц! Многие сайты используют префиксы таблиц, поэтому обязательно проверяйте свои запросы, прежде чем пытаться использовать их в привязке @SELECT. Если в вашем запросе есть ошибка, MODX зарегистрирует ошибку в журнале ошибок.

Следующий шаг: форматирование

Итак, вы можете вернуть кучу данных из базы данных ... и что теперь? Если вам нужно отформатировать его разумно, вы можете получить некоторое преимущество от выходных визуализаций, но вы можете найти доступные варианты, ограничивающие вас. Вы можете написать свой собственный Сниппет который форматирует значение переменной шаблона.

Безопасность

Позволяет ли эта привязка выполнять запросы UPDATE, INSERT или DELETE (или операторы gasp, DROP TABLE)? Даже если это не поддерживает directly, вы можете создать и выполнить сложный запрос, который SELECT является результатом такого разрушительного запроса. По крайней мере, пользователь может создать запрос, чтобы выбрать хэш пароля другого пользователя или просмотреть документы, к которым у пользователя нет доступа. Многие CMS предоставляют полный доступ к базе данных (включая операторы DROP и DELETE) с дескриптором базы данных, используемым приложением. Это опасно, и привязка @SELECT может раскрыть некоторые из тех же уязвимостей.

Смотрите также

Support the team building MODX with a monthly donation.

The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.

Backers

  • modmore
  • modmore
  • Jens Wittmann – Gestaltung & Entwicklung
  • Raffy
  • eydolan
  • Digital Penguin
  • Fabian Christen
  • Dannevang Digital
  • deJaya
  • Following Sea
  • Sepia River Studios
  • Anton Tarasov
  • Lefthandmedia
  • Nick Clark
  • Chris Fickling
  • Murray Wood
  • YJ
  • CrewMark
  • Richard

Budget

$305 per month—let's make that $500!

Learn more