Операторы
Оператор — вторая часть элемента фильтра: { field, operator, value }. Здесь собраны все
поддерживаемые операторы, SQL, в который каждый превращается, и таблица того, какие из них
принимает колонка в зависимости от объявленного типа.
Перечисление MGOperator
Строки — те же, что присылает MUI X DataGrid; отправляйте их из интерфейса как есть. Приведение к перечислению происходит при гидрации запроса: неизвестная строка отклоняется ещё до того, как запрос доберётся до схемы.
| Категория | Оператор | Case перечисления |
|---|---|---|
| Строковые | contains |
MGOperator::CONTAINS |
notContains |
MGOperator::NOT_CONTAINS |
|
startsWith |
MGOperator::STARTS_WITH |
|
endsWith |
MGOperator::ENDS_WITH |
|
| Равенство | equals |
MGOperator::EQUALS |
is |
MGOperator::IS |
|
not |
MGOperator::NOT |
|
= |
MGOperator::EQ |
|
!= |
MGOperator::NEQ |
|
| Сравнение | > |
MGOperator::GT |
>= |
MGOperator::GTE |
|
< |
MGOperator::LT |
|
<= |
MGOperator::LTE |
|
| Даты | after |
MGOperator::AFTER |
onOrAfter |
MGOperator::ON_OR_AFTER |
|
before |
MGOperator::BEFORE |
|
onOrBefore |
MGOperator::ON_OR_BEFORE |
|
| Множество | isAnyOf |
MGOperator::IS_ANY_OF |
| Пустота | isEmpty |
MGOperator::IS_EMPTY |
isNotEmpty |
MGOperator::IS_NOT_EMPTY |
Операторы для дат — синонимы операторов сравнения: они существуют потому, что интерфейс таблицы называет их иначе для колонок-дат, а SQL получается тот же.
Оператор → SQL
| Оператор | SQL |
|---|---|
contains |
col LIKE :v со значением %v% * |
notContains |
col NOT LIKE :v со значением %v% * |
startsWith |
col LIKE :v со значением v% * |
endsWith |
col LIKE :v со значением %v * |
equals · is · = |
col = :v |
not · != |
col != :v |
> · after |
col > :v |
>= · onOrAfter |
col >= :v |
< · before |
col < :v |
<= · onOrBefore |
col <= :v |
isAnyOf |
col IN (:v0, :v1, …) — пустой набор даёт пустое условие |
isEmpty |
col IS NULL |
isNotEmpty |
col IS NOT NULL |
* Четыре первых оператора регистронезависимы, а в SQL это пишется по-разному в разных
СУБД: ILIKE в PostgreSQL, LIKE в MySQL и SQLite, lower(col) LIKE lower(:v) как
портируемый вариант. Написание выбирается автоматически — см.
Режимы совпадения.
Значение всегда уходит связанным параметром: подстановка % в шаблон делается на стороне
PHP, а не склейкой строк в SQL.
Перечисление FilterType
Тип объявляется у колонки через filterable() и работает шлюзом: оператор вне набора
отклоняется с кодом 400 до того, как дойдёт до SQL. Это защищает запрос не только от
злонамеренного, но и от просто неверно настроенного интерфейса.
FilterType |
Разрешённые операторы |
|---|---|
String |
contains, notContains, startsWith, endsWith, equals, is, not, =, !=, isAnyOf, isEmpty, isNotEmpty |
Number |
equals, is, not, =, !=, >, >=, <, <=, isAnyOf, isEmpty, isNotEmpty |
Boolean |
is, equals, =, isEmpty, isNotEmpty |
Date |
is, not, equals, =, !=, after, onOrAfter, before, onOrBefore, isEmpty, isNotEmpty |
Та же матрица, если смотреть со стороны оператора:
| Оператор | String |
Number |
Boolean |
Date |
|---|---|---|---|---|
contains · notContains · startsWith · endsWith |
✓ | — | — | — |
equals · is · = |
✓ | ✓ | ✓ | ✓ |
not · != |
✓ | ✓ | — | ✓ |
> · >= · < · <= |
— | ✓ | — | — |
after · onOrAfter · before · onOrBefore |
— | — | — | ✓ |
isAnyOf |
✓ | ✓ | — | — |
isEmpty · isNotEmpty |
✓ | ✓ | ✓ | ✓ |
Выбирайте тип по поведению значения в SQL
Тип здесь — не про тип в PHP, а про то, какие сравнения имеют смысл. Колонку со статусом,
которую сравнивают только на равенство и вхождение в набор, разумно объявить String, даже
если в базе это smallint. А метку времени — Date, чтобы получить операторы диапазона и
не получить contains.
Пример отказа
GridColumn::for('views', 'a.views')->filterable(FilterType::Number);{ "field": "views", "operator": "contains", "value": "1" }{ "message": "Operator 'contains' is not allowed for field 'views'" }Объединение условий: AND и OR
Поле logicOperator модели фильтров решает, как складываются элементы. Значение
проверяется на этапе гидрации: принимаются только and и or в любом регистре, по
умолчанию — and.
{
"filterModel": {
"logicOperator": "or",
"items": [
{ "field": "title", "operator": "contains", "value": "sql" },
{ "field": "authorName", "operator": "contains", "value": "sql" }
]
}
}Результат
((a.title LIKE :iqb0 OR au.name LIKE :iqb1))Внешние скобки добавляются намеренно: без них OR смешался бы с вашим базовым WHERE
через AND и изменил смысл запроса.
Крайние случаи
| Случай | Поведение |
|---|---|
items пуст |
условие не добавляется, базовый WHERE не тронут |
isAnyOf с пустым массивом |
элемент пропускается, остальные применяются |
| все элементы дали пустое условие | условие не добавляется |
value отсутствует у isEmpty / isNotEmpty |
нормально, значение этим операторам не нужно |
| неизвестная строка оператора | 400 на этапе гидрации запроса |
| поле не объявлено в схеме | 400 из схемы |
Что дальше
- Режимы совпадения — как пишутся четыре регистронезависимых оператора.
- Свои фильтры — переопределение сопоставления для конкретной колонки.
- Справочник API —
filterable()и соседние методы.