array_unique不删除重复值php

时间:2017-11-19 14:02:11

标签: php mysql arrays string duplicates

很抱歉,如果这是重复的,我尝试过搜索,但似乎无法找到答案。我可能只是把这段代码放在错误的地方。

我已计算从各种选择框输入的重复值,这些选择框是通过$ _GET发送的。使用这些重复项,如果超过(无论设置的数量是多少),那么它将运行mysql查询。这一切都很好。

问题是我需要删除从mysql查询返回的重复项。这是我的代码:

if ($countGearSelected >= 2) {      
        $gearSets = array_keys(array_filter(array_count_values($_GET['gearPiece']), function($v) {
            return $v > 1;
        }));

        foreach ($gearSets as $gearSetKey => $gearSetValue) {

            $result = mysqli_query($con,"SELECT twoPieceBonus FROM sets WHERE setName='".$gearSetValue."';");
            while($row = mysqli_fetch_array($result)){

                $twoPieceBonus .= urldecode($row['twoPieceBonus']).'</br></br>';

            }
            $twoPieceBonus = implode(',',array_unique(explode(',', $twoPieceBonus)));
            $twoSelected = substr($twoPieceBonus, 0, -10);

        }


    }else{
        $twoSelected = '';
    }

正如您所看到的,我在SE上的其他各个帖子上尝试了array_unique选项,但它似乎没有起作用。我想我可能会错误地使用它?

使用DISTINCT在mysql查询中不起作用,因为正在查询的一些“集合”具有相同的结果(如果这有意义吗?)。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

首先:您的代码容易受到SQL injection的攻击:使用prepared statements来避免这种情况。

其次,在循环的每次迭代中执行查询通常是个坏主意。在这种情况下,可以避免。您可以使用where运算符代替所有in子句中的相等比较,并一次性比较所有齿轮组。

这也将解决获得不同价值的问题。只执行一个查询,现在可以使用distinct

以下是代码的外观。我无法测试这个,但我预计错误(如果有的话)可以轻松修复:

$twoSelected = '';
if ($countGearSelected >= 2) {      
    $gearSets = array_keys(array_filter(
        array_count_values($_GET['gearPiece']), function($v) {
            return $v > 1;
        }
    ));

    // Create comma separated list of question marks
    $placeHolders = implode(",", array_fill(0, count($gearSets), "?"));
    // Prepare SQL statement with it
    $stmt = mysqli_prepare($con, 
            "SELECT DISTINCT twoPieceBonus 
             FROM sets 
             WHERE setName IN ($placeHolders);");

    // All gearSet values are strings:
    $types = str_repeat("s", count($gearSets));
    // Turn the gearSets into references
    $gearSetRefs = [];
    foreach ($gearSets as $i => $_) {
         $gearSetRefs[] = &$gearSets[$i];
    }
    // Bind arguments
    mysqli_stmt_bind_param($stmt, $types, ...$gearSetRefs); // the splat operator
    // Now we are all set to (safely) execute the query 
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    // Let the result of the URL decoding still be an array
    $twoPieceBonus = [];
    while ($row = mysqli_fetch_array($result)) {
        $twoPieceBonus[] = urldecode($row['twoPieceBonus']);
    }
    mysqli_stmt_close ($stmt);
    // ... and then use implode to insert those HTML breaks
    $twoSelected = implode("</br></br>", $twoPieceBonus);
}