我是php / SQL的新手(1天)所以请原谅我,如果我是以倒退的方式做这件事。
下面的这个php旨在将100个最近的条目返回到数据库中。我尝试通过选择要返回的100个条目来进行,并按条目的日期(时间戳)排序。这会将100个最近的条目返回给DB吗?或者我理解这个错误?
$type = isset($_GET['type']) ? $_GET['type'] : "global";
$offset = isset($_GET['offset']) ? $_GET['offset'] : "0";
$count = isset($_GET['count']) ? $_GET['count'] : "100";
$sort = isset($_GET['sort']) ? $_GET['sort'] : "date DESC";
// Localize the GET variables
$udid = isset($_GET['udid']) ? $_GET['udid'] : "";
$name = isset($_GET['name']) ? $_GET['name'] : "";
// Protect against sql injections
$type = mysql_real_escape_string($type);
$offset = mysql_real_escape_string($offset);
$count = mysql_real_escape_string($count);
$sort = mysql_real_escape_string($sort);
$udid = mysql_real_escape_string($udid);
$name = mysql_real_escape_string($name);
// Build the sql query
$sql = "SELECT * FROM $table WHERE ";
switch($type) {
case "global":
$sql .= "1 ";
break;
case "device":
$sql .= "udid = '$udid' ";
break;
case "name":
$sql .= "name = '$name' ";
break;
}
$sql .= "ORDER BY $sort ";
$sql .= "LIMIT $offset,$count ";
$result = mysql_query($sql,$conn);
if(!$result) {
die("Error retrieving scores " . mysql_error());
}
//echo $result;
$rows = array();
while($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
答案 0 :(得分:2)
这应该有效,虽然date
是MySQL关键字,因此您需要将date
括在反引号中或重命名该列。
此外,肯定确保您在构建查询之前已对这些输入进行了清理。从$_GET
或$_POST
建立一个用户可编辑值的查询,没有卫生条件非常不安全。
对于WHERE
参数,你应该对那些(我看到你是,我不确定你以前是否有)的mysql_real_escape_string()
运行。这就足够了,因为你在查询中将这些值包装在引号中,并且因为你正在转义那个字符串,所以任何打破这些引号的尝试都不会起作用。
对于像ORDER BY
这样的东西,我会定义一个允许值的有效“列表”,并检查以确保您的参数在该列表中。例如:
$valid_orderbys = array('`date` DESC', '`date` ASC', '`name` DESC', '`name` ASC');
if (in_array($_GET['sort'], $valid_orderbys))
{
// you're good, you can use this value
}
else
{
// unexpected value, either alert the user or
// use a default value you define
}
或者对于LIMIT
,您可以使用PHP的内置is_numeric()
来验证您给出的值是数字,而不是精心设计的字符串。
不足以简单地转义$table
,ORDER BY
和LIMIT
参数,因为它们没有用引号括起来,因此有人可能只是恶意地注入值; DROP TABLE whatever; --
。这最终会使您的查询类似于:
SELECT * FROM ; DROP TABLE whatever; --WHERE ...
查询以分号分隔,因此这里有三个查询。第一个失败,因为它无效,第二个成功删除表,第三个只是注释,所以没有任何反应。但是你可以看到,如果你让用户扔出他们想要的任何一个参数,它就是一个广泛的安全漏洞。 (我不确定在反引号中包含表名是否有助于此,如果您知道,有人会通知我。但无论如何,您可以对LIMIT
和ORDER BY
参数执行相同的攻击。 )
答案 1 :(得分:0)
实际上,你已经做对了。您应该只考虑指定列而不是使用*。
答案 2 :(得分:0)
如果每个记录都有一个唯一的自动增量ID(如您所愿),ORDER BY id DESC
会更有效。