PHP根据值对多维数组进行排序,但得到意外结果

时间:2018-10-22 17:46:04

标签: php database mysqli multidimensional-array

所以我一直在这个问题上摸爬了一段时间,几乎到了那里,但仍然得到了意外的结果。

所以我有一个包含以下数据的数据库

username |  level1    |  level2    |  level3
user1    |  39.76072  |  79.41869  |  151.2955
user2    |  39.80072  |  80.73846  |  270.6498
user3    |  39.84072  |  80.81845  |  83.41801
user4    |  39.85321  |  80.90525  |  88.31719
user5    |  Zero      |  Zero      |  Zero

我一直试图按照从最低到最高的顺序将它们放入多维数组中,但确实很费劲。这些基本上是关卡时间,我正在尝试创建排行榜。

我认为问题在于级别列不是INT而是CHAR

我目前正在尝试以下

function order_by_time($a, $b) {
    return $b["Level".$_POST["level"]] < $a["Level".$_POST["level"]] ? 1 : -1;
}


$query = mysqli_query($con, "SELECT userName, Level".$_POST["level"]." FROM table");
$results = array();
$unranked = array();
while($line = mysqli_fetch_array($query, MYSQLI_ASSOC)){
    if($line["Level".$_POST["level"]] == "Zero"){
        $unranked[] = $line;
    } else{
        $results[] = $line;
    }
}
usort($results, "order_by_time");
$results = array_merge($results, $unranked);

这适用于级别1和级别2,但不适用于级别3。 Level1的显示方式与aboce数据库示例中的显示方式相同,level2的显示方式也是如此,但问题是level3的显示方式也是如此,这不是正确的顺序。

这似乎与小数点前的字符数有关。

有关如何解决此问题而不接触数据库的任何建议?确实不是一个选择,因为它已经被使用了。

我非常感谢您的帮助:-)

2 个答案:

答案 0 :(得分:0)

首先,请勿将$_POST中的某些内容直接注入SQL查询中。这就是网站被黑客入侵的方式。在这种情况下,建议您将变量设置为强制转换为整数,并检查其值:

$level = (int)$_POST["level"];
if ($level > 0 && $level < 4) {
    $query = $con->query("SELECT userName, Level$level FROM table");
} else {
    die();
}

对于您的问题,这里的简单解决方案是对数据库进行排序。 ORDER BY Level$level,您就完成了。

$level = (int)$_POST["level"];
if ($level > 0 && $level < 4) {
    $query = $con->query("SELECT userName, Level$level FROM table ORDER BY Level$level");
} else {
    die();
}
$results = $query->fetch_all(MYSQLI_ASSOC);

如果由于某种原因无法做到这一点,那么根据我的测试,您所能达到的效果应该很好。但这是很棘手的事情,尤其是将信息从$_POST拉到自定义函数中。相反,只需使用PHP的内置功能即可处理多维数组。

$level = (int)$_POST["level"];
if ($level > 0 && $level < 4) {
    $query = $con->query("SELECT userName, Level$level FROM table");
} else {
    die();
}
$results = $query->fetch_all(MYSQLI_ASSOC);
$usernames = array_column($results, "username");
$times = array_column($results, "Level$level");
array_multisort($times, SORT_ASC, $results);

答案 1 :(得分:0)

我能想到的唯一原因是,值中存在一些前导或尾随空格,阻止它们转换为用于比较的数字。

如果只是用HTML回显它们,则可能看不到空格,但是如果您(5,), 3变量,则会看到它们。 PHP的正常行为是将数字字符串作为数字进行比较,但是如果有多余的空格,它将无法正常工作。

var_dump

尝试修整值。

$test = '151.2955' > '83.41801';
var_dump($test); // true
$test = '151.2955 ' > '83.41801 ';
var_dump($test); // false

表达式是别名的,因此在PHP代码中将其称为$query = mysqli_query($con, "SELECT userName, TRIM(Level3) AS userValue FROM table"); ,而不要使用$row['userValue']中的值。如果可行,它还可以让您在MySQL中使用$_POST。我不太确定空格是否与PHP中的结果相同。我认为您需要将列强制转换为数字类型,以使其能够正确排序(不考虑空格)。不幸的是,您无法更改表格将数字存储为数字。