CakePHP преобразует целые числа MySQL в строки ... испортить функцию rand () - PullRequest
3 голосов
/ 29 января 2011

Я хочу получить случайную выборку данных из моей базы данных, используя 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 отправляет в БД, всегда делает this в часть RAND (), отправляя MySQL в шипение:

ORDER BY RAND(`1235123412341`)

Тестирование на ручном запросе, оно прекрасно работает и возвращает образец, когда он отформатирован следующим образом:

ORDER BY RAND(1235123412341)

Есть ли способ заставить Cake отказаться от автоформатирования? Все, что я помещаю в эту функцию RAND (), сбрасывается в строковые кавычки.

Ответы [ 2 ]

4 голосов
/ 29 января 2011

Все, что я помещаю в эту функцию RAND (), сбрасывается в строковые кавычки.

Нет, это не правильно. Если бы он использовал строковые кавычки, он бы работал нормально, однако обратные пометки не являются строковыми кавычками. Проблема в том, что CakePHP заключает в кавычки число, как если бы это было имя столбца . Попробуйте вместо этого заключить в кавычки значение:

"RAND('%d')"

Это должно привести к созданию следующего SQL:

ORDER BY RAND('1235123412341')

Это дает тот же результат, что и когда вы не включаете кавычки.

0 голосов
/ 29 января 2011

многие приложения и платформы пытаются использовать так называемое интеллектуальное определение типа переменной перед тем, как вставить их в базу данных

однако, многие из них также терпят неудачу с целыми числами и строками:)

из-за PHP автоматической типизации вы можете выполнить следующую проверку: is_int ('01234') и это вернет TRUE - но на самом деле не верно - «число» на самом деле является строкой, начинающейся с 0, и поэтому должно обрабатываться (если только вручную не преобразовано в целое число, если это именно так и должно быть)

вам нужно настроить класс базы данных CakePHP, где он проверяет типы данных

Я не знаком с CakePHP, но CodeIgniter использовал следующую проверку в своей функции escape ():

if (is_string($str))

... который я изменил на:

if (is_string($str) && (mb_strlen((int) $str) != strlen($str)))

... и теперь все это работает:)

P.S.: Я пытался использовать (int) $ str === $ str, однако это всегда давало неверный результат

...