[РЕШЕНО] Мозгодробилка с $c->where() в функции prepareQueryBeforeCount в процессоре расширяющем modObjectGetListProcessor
[Убийца — дворецкий]
Проблема была в типе данных по которым производился поиск. Заменил на varchar
Привет, коллеги!
Столкнулся с такой мозголомкой.
Есть процессор, который обрабатывает поиск в менеджере.
На входе ассоциативный массив.
Процессор расширяет modObjectGetListProcessor
В функции prepareQueryBeforeCount я формирую запрос. Формирую where через foreach:
Выборка и джойны нас не интересуют — там всё норм, а вот то что происходит по результатам работы метода where() — это весьма интересно, и для меня в какой-то мере загадочно.
Итак.
На входе массив:
$this->where выглядит следующим образом:
Причем не имеет значения, текст искать или цифры, все поля заполнять или только одно — все значения кроме name постоянно равны 0.
Происходит это если входное значение мы дополняем хотя бы одним знаком "%" при помощи конкатенации. Причем будет это записано как "%$v%" или "%".$v."%" — не важно. Результат всегда одинаковый — все кроме name — нули.
Сначала я думал, что проблема в типе данных, поскольку name — varchar, а остальные — text ( не спрашивайте почему, т.к. приложение разрабатывал не я :) ), но потом мысль эту от себя отогнал, потому что какая разница, если в самом SQL запросе нули.
Кто сталкивался?
Предлагайте куда копнуть.
Задавайте уточняющие вопросы.
Предлагайте эксперименты :)
MODX 2.6.5-pl
PHP 7.2.1
Проблема была в типе данных по которым производился поиск. Заменил на varchar
Привет, коллеги!
Столкнулся с такой мозголомкой.
Есть процессор, который обрабатывает поиск в менеджере.
На входе ассоциативный массив.
Процессор расширяет modObjectGetListProcessor
В функции prepareQueryBeforeCount я формирую запрос. Формирую where через foreach:
foreach ($query as $k => $v){
$this->where[$k.':LIKE'] = "%$v%";
}
$c->where($this->where);Для проверки использую $c->toSql().Выборка и джойны нас не интересуют — там всё норм, а вот то что происходит по результатам работы метода where() — это весьма интересно, и для меня в какой-то мере загадочно.
Итак.
На входе массив:
[$query] => Array
(
[id] => 100
[city] => 200
[name] => 300
[phone] => 400
[mail] => 500
[performer] => 600
)Я просто поставил циферки в каждое поле поиска.$this->where выглядит следующим образом:
[$this->where] => Array
(
[id:LIKE] => %100%
[city:LIKE] => %200%
[name:LIKE] => %300%
[phone:LIKE] => %400%
[mail:LIKE] => %500%
[performer:LIKE] => %600%
)И после обработки, в части кода, который сформирован методом where() у нас получается вот что:WHERE ( `a`.`id` LIKE 0 AND `a`.`city` LIKE 0 AND `a`.`name` LIKE '%300%' AND `a`.`phone` LIKE 0 AND `a`.`mail` LIKE 0 AND `a`.`performer` LIKE 0 )ВСЕ значения КРОМЕ name нулевые.Причем не имеет значения, текст искать или цифры, все поля заполнять или только одно — все значения кроме name постоянно равны 0.
Происходит это если входное значение мы дополняем хотя бы одним знаком "%" при помощи конкатенации. Причем будет это записано как "%$v%" или "%".$v."%" — не важно. Результат всегда одинаковый — все кроме name — нули.
Сначала я думал, что проблема в типе данных, поскольку name — varchar, а остальные — text ( не спрашивайте почему, т.к. приложение разрабатывал не я :) ), но потом мысль эту от себя отогнал, потому что какая разница, если в самом SQL запросе нули.
Кто сталкивался?
Предлагайте куда копнуть.
Задавайте уточняющие вопросы.
Предлагайте эксперименты :)
MODX 2.6.5-pl
PHP 7.2.1
Комментарии: 19
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
нормальный формируется?
М.б. его кто-то еще ухитряется поменять? Попробуй другую переменную, локальную использовать.
(
[id:LIKE] => %100%
[city:LIKE] => %200%
[name:LIKE] => %300%
[phone:LIKE] => %400%
[mail:LIKE] => %500%
[performer:LIKE] => %600%
)
Там как раз фишка в работе where()
Если в цикле убрать "%", то в выходном SQL все значения правильные. Но тогда запрос SQL будет не корректным, потому что для поиска надо чтобы были "%"
а не
на худой конец
В нее я пишу массив значений, чтобы потом скопом их указать в
Даже если я сразу укажу в цикле, результат будет такой же.
Очистил кэш и папку с кэшнм до кучи :)
Но результата нет.
Может, есть еще какое заклинание?
Я всё так и сделал, но есть один нюанс. Реализация, как я говорил, не моя и там оказалось несколько CMP с очень похожими названиями и в БД таблицы тоже с похожими названиями и схожей структурой таблиц. То есть столбцы с одинаковыми названиями.
Так вот в таблице я поменял в которой надо, а файл .map.inc.php менял другой :)
Ну, теперь в обоих CMP будет всё как надо.
П.С. Где мой плюс? :)
Стрелку апнул ;)
И еще раз, мерси боку!
Можешь рассказать подробнее, что ты имеешь в виду?
что делает метод where ?
он всего лишь пишет в массив $this->query['where'] условия. Я тебе и предлагал туда записать условия напрямую в виде sql
первый запрос
даст нам
как видим запрос типа кривой, но результат выдал 2. Странно да? Уже повод задуматься…
Давай выполним второй запрос, минуя метод where
результат
Итог: в первом и втором запросе мы получили нужный результат. Так в чем же дело?
ps. Вообщем не факт что твоя ошибка была в этом месте… совсем не факт. Просто при toSQL
выполняется parseBindings что приводит запрос к такому виду…
Это очень ценная информация!
В итоге я еще обнаружил, что почти все поля по которым происходил поиск в схеме имели вместо 'phptype' => 'string', 'phptype' => 'text'
Я вообще теряюсь в догадках, как у заказчика это всё работало раньше, при таких косяках в коде.
Дело в том, что сайт был заражен и его как-то кто-то починил, после чего перестала работать система учета. Хоть заново всё пиши.