2010-07-08 67 views
3

我正在使用php并在mysql服务器上运行sql查询。 为了防止sql注入,我正在使用mysql_real_escape_string。如何投射bigint,以防止在PHP中的SQL注入?

我也使用(INT),用于数字铸造,以下列方式:

$desired_age = 12; 
$query = "select id from users where (age > ".(int)$desired_age.")"; 
$result = mysql_query($query); 

这项工作。

但是,当变量包含较大数字时,由于它们大于int,因此它们失败。

$user_id = 5633847511239487; 
$query = "select age from users where (id = ".(int)$user_id.")"; 
$result = mysql_query($query); 
// this will not produce the desired result, 
// since the user_id is actually being cast to int 

有另一种方式投下大量(如BIGINT),除了使用mysql_real_escape_string的,当涉及到SQL注入预防?

+0

这里也有一个问题$ user_id = 5633847511239487;将不会持有你的想法,并且没有办法让这个数字返回,你需要把它保存为一个字符串,而不是一个int - $ user_id ='5633847511239487'; – nathan 2010-07-08 13:58:19

+0

而不是处理消毒输入的麻烦,使用参数化查询来避免SQL注入。 http://bobby-tables.com/php.html在PHP中向你展示了如何。 – 2012-12-12 21:56:58

回答

3

您可以使用类似:

preg_replace('/[^0-9]/','',$user_id); 

替换字符串中的所有非数字符号。 但实际上没有必要这样做,只要使用mysql_real_escape_string(),因为一旦建立$ query,您的整数值将被转换为字符串。

+0

...只是发布这与is_numeric形成对比,这也允许浮动值,如“1.12”,这可能不完全是耶胡达想要的:) – michael 2010-07-08 14:01:22

+0

我测试了preg_replace解决方案,发现它限于14个字符。 所以我使用mysql_real_escape_string字符串和数字用户输入。 tnx大家 – yehuda 2010-07-09 09:14:40

1

验证输入。如果它是一个数字,不要只是简单地逃避它,验证它。这儿有几个PHP功能,这做的伎俩,比如is_numeric()来 - 检测变量是否为数字或数字字符串

http://www.php.net/is_numeric

10

如果生成自己的用户ID,没有必要因为没有SQL注入或其他字符串问题的机会,所以将其转换为MySQL。

如果是用户提交的值,则使用filter_var()(或is_numeric())来验证它是一个数字而不是字符串。

+0

也会说同样的事情,铸造是有用的,但只适用于查询字符串中不是用户输入结果的数字。它阻止人们操纵查询字符串。至于用户输入,检查值是否是数字是最好的选择,因为它允许您给出友好的消息。 – 2010-07-08 13:57:55

1

使用服务器端准备好的参数化语句(并因此删除对xyz_real_escape_string())的需要和/或将该ID作为字符串处理。 MySQL服务器内置了字符串< - >数字转换的规则,如果您决定更改为id字段的类型/结构,则不必更改php代码。除非您有(微)优化的具体需求,否则通常不需要让代码对数据库中id字段的结构和值范围做出这种假设。

$pdo = new PDO('mysql:...'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$stmt = $pdo->prepare('SELECT age FROM users WHERE id=?'); 
$stmt->execute(array('5633847511239487')); 
0

经过一番研究,我得出了这样的设置

private function escapeInt($value) 
{ 
    if (is_float($value)) 
    { 
     return number_format($value, 0, '.', ''); // may lose precision on big numbers 
    } 
    elseif(preg_match('/^-?[0-9]+$/', $value)) 
    { 
     return (string)$value; 
    } 
    else 
    { 
     $this->error("Invalid value"); 
    } 
} 

独立的情况下彩车因为$i = 184467440737095;成为浮在32位系统上,因此将崩溃,以科学记数法转换为字符串时, 。
而简单的正则表达式为休息

0

您甚至可以通过*1乘以变量,你可以检查它的最大值和最小值,你可以接受(年龄BIGINT是不是一种选择,在所有...那为什么还要允许数字超过你准备好的价值? 而且还有PDO与它的查询准备。