在运行MySQL之前验证PHP中的变量?

时间:2013-04-15 16:21:36

标签: php mysql validation get

我知道这个问题已被问了一百万次,但是今天(2013年)在SQL语句中运行变量之前验证查询字符串的标准是什么?

例如,如果我通过$ _GET ['id']从网址收到变量“id”:

$id = $_GET['id'];

......在跑步前我该怎么做:

SELECT * FROM users WHERE id="$id"

这就够了:

$id = mysql_real_escape_string($_GET['id']);

...对于这个具体的例子?

3 个答案:

答案 0 :(得分:1)

这是无关紧要的,因为在大多数传统情况下,id是一个整数。你必须使用:

$id = (int)$_GET['id'];

现在的标准方法是使用在MySQLi和PDO的库中表示的参数化查询/预处理语句。

对于任何手动验证,您需要明智地考虑您希望收到此变量的内容。

就像在这种情况下,你只期望整数,没有别的。您不需要人们通过ID发送 - > 1 UNION SELECT ...仍然是一个有效的字符串,mysql_real_escape_string将不会对它做任何事情。

答案 1 :(得分:1)

在这种情况下最简单的验证就是强制转换为整数。

<?php

$id = (int) $_GET['id'];

$sql = "SELECT * FROM users WHERE id=$id";

然后,您不需要在SQL表达式中的变量周围加引号。事实上,有些情况下,使用数字文字周围的引号会混淆SQL优化器,所以我总是很困惑为什么这么多人会养成这种习惯。

如果您想进行更复杂的验证,请阅读PHP's filter extension

最后,在SQL中使用变量的更好(更简单,更快速,更安全)的方法是使用查询参数。但是,PHP已弃用的mysql_*函数不支持查询参数,因此您应该了解mysqliPDO

答案 2 :(得分:1)

您可能应该从已弃用的mysql_切换到mysqli,在那里您可以利用允许您使用占位符的mysql::prepare()

$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?");
$stmt->bind_param("s", $city);
$stmt->execute();

哪个和SQL一样安全。

mysql_real_escape_string()足以阻止SQL注入(只要将字符串括在引号中)。