2011-09-07 148 views
2

我正在开发一个房地产脚本。该脚本有一个搜索选项,用户可以指定价格范围,例如。 user_price_low到user_price_high,并且列表必须从数据库中获取,该数据库具有例如。 db_price_high和db_price_low。Mysql ...价格范围内的价格范围?

我用之间的语句试图找到匹配项,

WHERE price_low BETWEEN '.$_REQUEST['minprice_buy'].' AND '.$_REQUEST['maxprice_buy'] 

,但让我吃惊......

如果用户有user_price_high = 60和user_price_low = 20 和 记录有db_price_low = 30和db_price_high = 120

我的查询在这种情况下无效。

我试着看着MySql Query- Date Range within a Date Range但是这符合我想要的吗?

+6

另一个php文章,另一个SQL注入。 – Johan

+0

你是什么意思数据库有'price_low'和'price_high'?它不应该只是“价格”吗?显示更多的代码以及你的数据库表。 –

回答

4

Chandan,永远不会将$ _ *函数直接输入到查询中。这是一个SQL注入漏洞。

更改代码:

$min_price = mysql_real_escape_string($_REQUEST['minprice_buy']); 
$max_price = mysql_real_escape_string($_REQUEST['maxprice_buy']); 
$query = "SELECT whatever 
      FROM whichever 
      WHERE price_low BETWEEN '$min_price' AND '$max_price' "; 
// Dont forget these quotes  ^  ^ ^  ^
// Or mysql_real_escape_string() will not work!. 

至于你的问题,查询更改为类似:

WHERE '$min_price' BETWEEN price_low AND price_high 
    AND '$max_price' BETWEEN price_low AND price_high 

您可能还需要考虑:

WHERE ('$min_price' BETWEEN price_low AND price_high) 
    OR ('$max_price' BETWEEN price_low AND price_high) 

这里min_pricemax_price不需要都在这个范围内秒。

参见:How does the SQL injection from the "Bobby Tables" XKCD comic work?

+0

你的回答并不完全正确,我不认为。它需要包容性(OR),而不是排他性(AND)。 –

+0

感谢您的快速回答。我试着按照你的建议放入查询,一切似乎都正常。不过,我会再测试一下,以确保没有更多的错误。我appriciate你也提醒我关于SQL注入。不过,我做了$ _REQUEST ['minprice_buy'] = mysql_real_escape_string($ _ REQUEST ['minprice_buy'])的检查;不会那么好吗? – chandan

+0

这只是复杂的东西,我推荐上面的代码,它更容易阅读和理解。此外,不需要事先拒绝代码,让查询运行,否则攻击者会通过检查代码中的时间差异来知道自己正在测试的内容,并将其攻击重点放在花费更长时间返回的代码上,即代码你忘了参加测试。 – Johan

-2

所以accourding什么,我明白了,不应该说,它是

WHERE price_low >= '.$_REQUEST['minprice_buy'].' AND price_high <='.$_REQUEST['maxprice_buy']' 

在查询中使用它们之前验证使用mysql_real_escape_string();您的输入,不使用$ _GET,$ _REQUEST,$ _ POST变量直接在任何查询中。

+1

-1,你不能在这样的答案中留下一个明显的SQL注入漏洞,并希望得到upvotes。哦,答案不正确,WHERE X> = MIN且y <= max'不能保证(min Johan

+0

@Johan为什么要保证在这种情况下(min Pheonix

+1

因为如果Min = 50000且Max = 1,它们都不在该范围内。 – Johan

2

如果你想检查的范围有什么共同点,你应该使用

WHERE greatest(price_low,user_price_low)<=least(price_high,user_price_high) 

如果要检查,如果用户的范围是所有范围,你可以使用
未定义行为user_preice_low>user_price_high

WHERE user_price_low>=price_low && user_price_high<=price_high 
+0

SQL ()函数不能像那样工作,你需要使用最大()函数。如果'user_price_low = 50000和user_price_high = 1',即使值不在该范围内,您的查询也会返回true。 – Johan

+0

@Johan:函数名是固定的。对于'user_price_low = 50000和user_price_high = 1' res先查询就OK了。第二个查询将返回一些行,但它可能会在客户端(我将添加信息)检查 – RiaD

+0

我放弃了-1,因为顶部线是正确的,但底线不是。请注意,使用函数将会消除使用索引的可能性。哪些不会令人满意的查询。 – Johan