ORDER BY 与准备好的语句

ORDER BY with prepared statements

我目前正在编写一个脚本,它可以根据用户输入对数据库 table 进行排序。

因此,用户可以选择一个列(通过选择框),然后整个 mysql table 应该按照选择框值的顺序显示。

我现在的代码($order是用户输入)

对于这种格式,我很抱歉,我在移动设备上:/

$order = "user_id"; //user input

$sql = $db->prepare("SELECT user_id, username, realname, auth_lvl, usercolor, activated, ban FROM users ORDER BY ?");

$sql->bind_param('s', $order);
$sql->execute();
$sql->bind_result($id, $username, $realname, $auth_lvl, $usercolor, $activated, $ban);
$sql->store_result();

while ($sql->fetch()) {
    //echo...
}

问题

不管 $order(ORDER BY 部分)是什么,我总是得到这样的 ID 顺序:3、4、5、30、29

如果输入参数是'foo',那么你的SQL就相当于

SELECT user_id, username, realname, auth_lvl, usercolor, activated, ban 
FROM users
ORDER BY 'foo'

这当然意味着行可以按任何顺序排列。您不能将参数用于 order by 子句和 table 名称。在这种情况下,您实际上需要将列的值作为字符串的前缀。

$q = 'SELECT user_id, username, realname, auth_lvl, usercolor, activated, ban FROM users ORDER BY ' . $order;

这显然容易受到SQL注入,所以需要手动确保列名有效:

$valid_col = in_array($order, ['username', 'realname', ...], true);

然后只有在结果为真时才执行查询。