MODX. &where, примеры записей условий для выборки (примеры предикатов)
Отредактировано: 24 Июля 2025
В случае, если надо конкретизировать условия выборки записей, используются предикаты — выражения которые в качестве результата возвращают TRUE, FALSE или UNKNOWN. В случае использования CMF MODX количество вариаций записи предикатов возрастает, из-за большого количества языков, которые понимает данная система.
Различия записей в языках:
SQL: WHERE width = 15
MODX: &where=`width = 15`
JSON в тегах MODX: &where = `{ "width":15 }` (данный тип записи в тегах MODX может срабатывать но заносить ошибку в лог)
xPDO: $query->where(array('width' => 15));
JSON в fenom: 'where' => '{"width":15}'
xPDO в снипете: 'where' => [ 'width' => 15]
Ссылка на официальную документацию
Множественный выбор с условиями
MODX: &where=`width = 15 OR width = 25`
xPDO: $query->where(array(array( 'width' => 15), array('OR:width:=' => 25)));
JSON: { "0": { "width :=":"15","AND:height:=":"10" },"OR:width :=":"25" }
xPDO в снипете: 'where' => [ 'width' => 15, 'OR:width:=' => 25 ]
Запрос с порядком вычисления в xPDO в снипете: 'where' => [ ['width ' => 15,' OR:where:=' => 20], 'AND:height:=' => 25],
Доступные операторы
| Символ | Пример xPDO | Пример MODX | |
| Равно | 'width' => 15 | `width = 15` | |
| = | 'width:=' => 15 | ||
| Равно (безопасное сравнение значения NULL) | <=> | ||
| Не равно | != | 'width:!=' => 15 | `width != 15` |
| <> | |||
| Больше | > | 'width:>' => 15 | `width > 15` |
| Меньше | < | 'width:<' => 15 | `width < 15` |
| Больше или равно | >= | 'width:>=' => 15 | `width >= 15` |
| Меньше или равно | <= | 'width:<=' => 15 | `width <= 15` |
| Содержит | LIKE |
'width:LIKE' => '%15%' Переменная в Fenom: 'width:LIKE' => '%'~$.get.tag~'%' |
`width LIKE %15%` |
| Не содержит | NOT LIKE | 'width:NOT LIKE' => '%15%' | `width NOT LIKE %15%` |
| В массиве | IN | 'width:IN' => array(15,16,17,20) | |
| Не в массиве | NOT IN | 'width:NOT IN' => array(15,16,17,20) | |
| NOT | `width NOT 15 ` | ||
| Если Null | IS | 'width:IS' => null | `width IS null` |
| IS NULL | `width IS NULL ` | ||
| Если Not Null | IS NOT NULL | 'width:IS NOT' => null | `width IS NOT NULL` |
| Между | BETWEEN | ||
| Включает | EXISTS | ||
| Не включает | NOT EXISTS | ||
| Соединяется | COALESCE | ||
| Интервал | INTERVAL | ||
| Наибольшее | GREATEST | ||
| Наименьшее | LEAST | ||
| Совпадает | MATCH | ||
| Максимум | MAX | ||
| Минимум | MIN | ||
| В среднем | AVG | ||
| Или | OR |
array( 'width' => 15), array('OR:width:=' => 10) |
|
| И | AND |
array( 'width' => 15), array('AND:height:=' => 10) |
|
| Регулярное выражение | REGEXP | `pagetitle REGEXP "MODX"` |
Трафаретные символы
При составлении предикатов (условий выборки) можно использовать трафаретные символы:
- символ подчеркивания (_) — означает любой единичный символ в проверяемом значении;
- символ процента (%) — означает последовательность любых символов в проверяемом значении. Количество символов в такой последовательности не ограничено (от 0 и более).
| Образец | Описание |
|---|---|
| 'abc%' | Любые строки, которые начинаются с букв «abc» |
| 'abc_' | Строки длиной строго 4 символа, причем первыми символами строки должны быть «abc» |
| '%z' | Любая последовательность символов, которая обязательно заканчивается символом «z» |
| '%word%' | Любая последовательность символов, содержащая слово «word» в любой позиции строки |
| '% % %' | Текст, содержащий не менее 2-х пробелов, например, "World Wide Web" |
Трафаретные символы открывают большой простор для творчества при создании предикатов:
# Где class не заканчивается на o, но не на go
WHERE class NOT LIKE '%go' AND class LIKE '%o' ;
С трафаретными символами может возникнуть проблема в случае если искомая строка будет содержать аналогичные символы, например, если надо отыскать все значения, содержащие символ «_», то шаблон ‘%_%’ приведет к тому, что будут возвращены все записи из таблицы. В этом случае поможет указание экранирующего символа в ESCAPE или экранирующий символ \.
# указываем что символ # является экранирующим
'%#_%' ESCAPE '#'
# назначить можно любой символ, в этом примере |
LIKE '25|%' ESCAPE '|'
# некоторые версии SQL в качестве экранирующего могут принимать обратный слеш (\),
# по примеру популярных языков программирования
'%\_%'
'25\%'
Теги MODX
[[pdoResources?
&where = `published=1,deleted=0,createdby=12`
...
]]
Для сложных конструкций можно использовать чанк, сниппет или плейсхолдер вместо строки:
[[pdoResources?
&where=`[[CalculatedWhere]]`
...
]]
пример такого сниппета:
$where = array(
'published' => 1,
'deleted' => 0,
'createdby' => $modx->user->get('id'),
);
return $modx->toJSON($where);
Json
Обратите внимание, что при использовании JSON записи одновременно с шаблонизатором Fenom, после фигурных скобок надо проставлять пробелы. Иначе запись может вызвать ошибку в логах, несмотря на то что код будет обработан правильно.
[[pdoResources?
&where = `{ "published":1,"deleted":0,"createdby":12 }`
...
]]
Использование плейсхолдеров
Плейсхолдеры должны формироваться до вызова ресурсов. К примеру сниппет SetWhere формирующий плейсхолдер:
$jsonString = $modx->toJSON($input);
$modx->setPlaceholder('CalculatedWhere', $jsonString);
Вызов сниппетов
[[SetWhere?
&input=`month=January,year=2015`
]]
[[pdoResources?
&where=`[[+CalculatedWhere]]`
...
]]
Несколько вызовов на странице можно сформировать добавив дополнительный параметр. Формирование плейсхолдера:
$placeholderName = $scriptProperties['ph']
// ...
$modx->setPlaceholder($placeholderName, $value);
Вызов на странице:
[[SetWhere?
$month=`January`
&year=`2015
&ph=`January`
]]
[[getResources?
&where=`[[+January]]`
...
]]
...
[[SetWhere?
$month=`February`
&year=`2015
&ph=`February`
]]
[[getResources?
&where=`[[+February]]`
...
]]
Примеры
Получение всех ресурсов, опубликованных в течение определенного месяца того или иного года
[[getResources?
&where=`[[CalculatedWhere? &month=`January` &year=`2015`]]`
...
]]
Сниппет CalculatedWhere
$month = $scriptProperties['month'];
$year = $scriptProperties['year'];
$a_date = $month . ' ' . $year;
$min = strtotime($a_date);
$time = date("Y-m-t 23:59", $min);
$max = strtotime($time);
$where = array(
'publishedon:>=' => $min,
'publishedon:<=' => $max,
);
return $modx->toJSON($where);
// будет сформирована JSON строка вида
// {"publishedon:>=":1420092000,"publishedon:<=":1422770340}
Данные какого-либо плейсхолдера входят в массив
[[pdoResources?
&where = `[[+id]] IN (1,2,3,4,5)`
...
]]
php конструкция, формирующая запрос where
// опубликованные ресурсы, не являющиеся каталогом
$where = array( 'published' => 1, 'isfolder' => 0, );
// формирование were из GET данных
$filter = array();
if($_GET['tags']) {
$filter[] = 'tags='.$_GET['tags'];
}
if($filter) {
$where = $modx->toJSON(array($filter));
} else {
$where = '';
}
$params = array(
...
'where' => $where
);
where и оператор like в php
$arr = array (5,15,10,20);
$params = array(
...
'where' => [
'field:LIKE' => '%'.$arr.'%',
'field2:LIKE' => $arr.'%',
'field3:LIKE' => '%'.$arr
],
...
);
$out = $modx->runSnippet('pdoPage', $params);
Возможные ошибки
- Если после составления условия where в логах возникает ошибка «Error parsing condition with key 0», то вероятно неправильно составлены критерии выборки. Например, отсутствует хотя бы 1 рабочий параметр: «pagetitle REGEXP "MODX"» выдаст ошибку, в то время как «isfolder = 0 and pagetitle REGEXP "MODX"» выведет искомый результат.