Отсутствие в PHP беззнаковых целочисленных значений и функция CRC32 в MySQL - PullRequest
4 голосов
/ 30 ноября 2011

Я сказал Sphinx индексировать некоторые строки в их формах CRC32 как атрибуты, например так:

sql_query = SELECT [...], CRC32(LOWER(color)) AS color, [...], FROM table

sql_attr_uint = color

Я пытаюсь запустить в PHP какой-то многогранный поиск, где пользователи могут щелкнуть ссылку содин из вышеперечисленных colors и Sphinx получит другой поисковый запрос с суженными результатами, например:

Previous page:
<h3>Narrow down results:</h3>
<p><a href="search.php?query=something&color=1678454">Red (11)</a></p>
<p><a href="search.php?query=something&color=4133605867">Yellow (5)</a></p>

<?php
    if (isset($_GET[$name]))
    {
        $sphinx->SetFilter('color', intval($_GET['color']));  // <-- Uh-oh
    }

    [...]

    $sphinx->Query($query, 'table');
?>

Здесь все идет не так, потому что MySQL CRC32 () возвращает 32-разрядное целое число без знака,PHP очень услужливо не поддерживает и шапки на 2 ^ 31-1.Приведенная выше ссылка на желтый цвет представляет мою проблему.

StackOverflow, что может быть приемлемым решением для этого?Я полагаю, что некоторые математические операции на стороне SQL-запроса возможны, но я опасаюсь, что вероятность столкновения станет еще хуже.

Заранее спасибо.

1 Ответ

2 голосов
/ 30 ноября 2011

Цитирование из справочной страницы PHP crc32 () :

Поскольку целочисленный тип PHP подписан, и многие контрольные суммы crc32 будут в результате получаются отрицательные целые числа, вам нужно использовать форматер "% u" sprintf () или printf (), чтобы получить строковое представление без знака контрольная сумма crc32.

Другими словами, PHP не может обрабатывать большие целые числа, но в этом конкретном случае вы можете эмулировать целые числа без знака с двойной точностью. Вы можете получить реальное значение при приведении к строке.

Этого должно быть достаточно, поскольку вам не нужно выполнять математические операции, такие как сложение или умножение.


Обновление: Полагаю, я просто проигнорировал важную часть вашего вопроса. Вместо этого:

intval($_GET['color'])

... вы можете проверять или фильтровать с помощью регулярного выражения:

preg_match('/^\d+$/', $_GET['color'])
preg_replace('[^\d]', '', $_GET['color'])

... и обрабатывать значение CRC как строку.

...