PHP 缺乏无符号整数和 MySQL 的 CRC32 函数

发布于 2024-12-18 21:08:01 字数 913 浏览 0 评论 0原文

我告诉 Sphinx 将其 CRC32 形式中的一些字符串作为属性进行索引,如下所示:

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

sql_attr_uint = color

我正在尝试在 PHP 中进行一些分面搜索,用户可以单击具有上述颜色之一的链接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 查询方面做一些数学计算是可能的,但我担心让令人担忧的冲突机会变得更糟。

提前致谢。

I told Sphinx to index some strings in their CRC32 forms as attributes, like so:

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

sql_attr_uint = color

I'm trying to get some faceted search going in PHP, where users can click on a link with one of the above colors and Sphinx would get another search request going with narrowed down results, something like:

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');
?>

Things goes wrong here because MySQL's CRC32() returns an unsigned 32-bit integer, which PHP very helpfully does not support and caps at 2^31-1. The above link for the color Yellow exposes my problem.

StackOverflow, what may be an acceptable workaround for this? I suppose doing some math on the SQL query side is possible, but I'm wary of making the worrying chance of collision even worse.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

热鲨 2024-12-25 21:08:01

引用 PHP 的 crc32() 手册页

因为PHP的整型是有符号的,很多crc32校验都会
结果为负整数,您需要使用“%u”格式化程序
sprintf() 或 printf() 获取无符号数的字符串表示形式
crc32 校验和。

换句话说,PHP 无法处理大整数,但在这种精确情况下,您可以将无符号整数模拟为双精度。当转换为字符串时,您可以获得真实的值。

这应该足够了,因为您不需要进行数学运算,例如加法或乘法。


更新:我想我只是忽略了你问题的重要部分。而不是这样:

intval($_GET['color'])

... 您可以使用正则表达式进行验证或过滤:

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

... 并将 CRC 值作为字符串处理。

Quoting from PHP's crc32() manual page:

Because PHP's integer type is signed, and many crc32 checksums will
result in negative integers, you need to use the "%u" formatter of
sprintf() or printf() to get the string representation of the unsigned
crc32 checksum.

In other words, PHP cannot handle large integers but in this precise case you can emulate unsigned integers to double precision. You can get the real value when casting to string.

This should be enough since you don't need to do mathematical operations, such as addition or multiplication.


Update: I guess I've just ignored the vital part of your question. Rather than this:

intval($_GET['color'])

... you can validate or filter with a regular expression:

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

... and handle the CRC value as string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文