Я хочу получить случайную выборку данных из моей базы данных с помощью CakePHP. Вот моя функция:
function categories_list() { $this->paginate['limit'] = 6; $this->paginate['order'] = ''; $this->paginate['conditions'] = ''; // Sort Randomly Start if ($this->Session->check('Category.randomSeed')) { $seed = $this->Session->read('Category.randomSeed'); } else { $seed = mt_rand(); $this->Session->write('Category.randomSeed', $seed); } $this->paginate['order'] = sprintf('RAND(%d)', $seed); // Sort Randomly End $this->set('cat_ajax_items', $this->paginate('Category')); }
Проблема в том, что запрос, который Cake отправляет в БД, всегда делает это с частью RAND (), отправляя MySQL в удобную форму:
ORDER BY RAND(`1235123412341`)
Тестирование по ручному запросу, оно работает просто отлично и возвращает образец, когда он отформатирован следующим образом:
ORDER BY RAND(1235123412341)
Есть ли способ заставить Cake отказаться от автоформатирования? Все, что я вложил в эту функцию RAND (), сбрасывается в строковые кавычки.
Все, что я вложил в эту функцию RAND (), сбрасывается в строковые кавычки.
Нет, это неправильно. Если он использовал строковые кавычки, тогда он будет работать нормально, однако обратные ссылки не являются строковыми кавычками. Проблема в том, что CakePHP цитирует число, как если бы оно было именем столбца . Попробуйте указать значение с помощью одинарных кавычек:
"RAND('%d')"
Это должно привести к созданию следующего SQL:
ORDER BY RAND('1235123412341')
Это дает тот же результат, что и при отсутствии котировок.
многие приложения и структуры пытаются использовать так называемое интеллектуальное определение типа переменной, прежде чем вставлять их в базу данных
однако многие из них также терпят неудачу с целыми числами и строками 🙂
из-за автоматического машинного моделирования PHP вы можете сделать следующую проверку: is_int ('01234'), и это вернет TRUE – но это на самом деле неверно – «число» на самом деле является строкой, начиная с 0 – и поэтому должно быть (если только вручную не преобразовать в значение до, если это то, что должно быть)
вам нужно будет настроить класс базы данных CakePHP, где он проверяет типы данных
Я не знаком с CakePHP, но CodeIgniter использовал следующую проверку в функции escape ():
if (is_string($str))
… который я изменил на:
if (is_string($str) && (mb_strlen((int) $str) != strlen($str)))
… и теперь все работает 🙂
PS: Я попытался использовать (int) $ str === $ str, однако это всегда приводило к некорректному результату