【问题标题】:PHP - Use array in mysqli queryPHP - 在 mysqli 查询中使用数组
【发布时间】:2018-11-18 12:07:31
【问题描述】:

PHP 新手在这里。这是我从中提取数据的 MySQL 数据库中的表的示例。

id  classA    classB     value
------------------------------
1   A         A          1
2   A         B          5   
3   A         C          2  
4   B         A          1
5   B         B          5   
6   B         C          1  
7   C         A          8
8   C         B          5   
9   C         C          7  

用户输入一个类类别列表(A、B、C 等),我的代码将返回这些对的每个组合的值(例如 [A,A]、[A,B]、[A ,C]...等)。我可以使用以下脚本轻松实现这一点,其中$array 是输入列表(例如[A,B,C]):

<?php
    // Mehtod 1 - slow
    for($i = 0; $i < count($arr); $i++){
        for ($j = 0; $j < count($arr); $j++){
            $sql = "SELECT value FROM data_table WHERE '$arr[$i]'=classA AND '$arr[$j]'=classB LIMIT 1";

            $value = mysqli_query($con,$sql);
            $value = mysqli_fetch_array($corr)[0];

            $results[] = array('classA' => $arr[$i], 'classB' => $arr[$j], 'value' =>  $value);
        }
    }
?>

但是,这很慢,因为 mysqli_query() 在 for 循环中。相反,我更愿意在一次调用中进行查询。我试过以下没有运气..

<?php
    // Mehtod 2 - fast
    for($i = 0; $i < count($arr); $i++){
        for ($j = 0; $j < count($arr); $j++){
            // make array of class combinations
            $query_array[] = array('classA' => $arr[$i], 'classB' => $arr[$j]);
        }
    }
    // get arrays of pairs to request
    $match1 = array_column($query_array, 'classA');
    $match2 = array_column($query_array, 'classB');

    $sql = "SELECT classA, classB, value FROM data_table WHERE classA IN '$match1' AND classB IN '$match2'";

    $results = mysqli_query($con,$sql);
    $results = mysqli_fetch_array($results);
?>

我可以用一个请求进行这样的查询吗?我有点卡住了。干杯。

【问题讨论】:

    标签: php mysql sql mysqli


    【解决方案1】:

    由于您需要所有可能的组合,因此您无需在 PHP 中构建组合然后在查询中使用它们。

    我宁愿做以下事情:

    SELECT classA, classB, value 
    FROM data_table
    WHERE classA IN ('A', 'B', 'C') AND 
          classB IN ('A', 'B', 'C')
    

    这将考虑所有组合。相当于:

    SELECT classA, classB, value 
    FROM data_table
    WHERE (classA = 'A' AND classB = 'A') OR
          (classA = 'A' AND classB = 'B') OR
          (classA = 'A' AND classB = 'C') OR
          (classA = 'B' AND classB = 'A') OR
          (classA = 'B' AND classB = 'B') OR
          (classA = 'B' AND classB = 'C') OR
          (classA = 'C' AND classB = 'A') OR
          (classA = 'C' AND classB = 'B') OR
          (classA = 'C' AND classB = 'C')
    

    在这种情况下,PHP 代码如下所示:

    <?php
        // Method 3 - possibly fastest and neater code
    
        // get comma separated values to match against
        $match_string = "('" . implode("','", $arr) . "')";
    
        $sql = "SELECT classA, classB, value 
                 FROM data_table 
                 WHERE classA IN " . $match_string . " AND 
                       classB IN " . $match_string;
    
        $results = mysqli_query($con,$sql);
        $results = mysqli_fetch_array($results);
    ?>
    

    最重要的是,为了避免SQL injection相关的攻击,你应该使用Prepared Statements

    【讨论】:

    • 非常感谢这个和关于 SQL 注入的说明。尽管我需要将implode(",'", $arr) 更改为implode("','", $arr)(逗号前的额外单引号)以生成$match_string,但我尝试了您的代码并使其运行。
    • 有了json_encode($results);,我又回来了{"0":"A","classA":"A","1":"B","classB":"B","2":"5","corr":"5"},而我追求的是[{"classA":"A","classB":"A","value":1},{"classA":"A","classB":"B","value":5},{"classA":"B","classB":"A","value":1},{"classA":"B","classB":"B","value":5}],为什么会产生这么乱的数组?
    • @Lachlan.00 你需要做一些错误操作。 MySQL 将仅以表格方式获取结果
    • 太好了,谢谢@Madhur,您能否推荐一个详细说明此类过程的链接?
    • 请注意,我通过以下方式解决了这个问题:while($row = mysqli_fetch_array($results, MYSQLI_NUM)){ $array[] = $row; }
    【解决方案2】:

    用户放入一个类别列表(A、B、C 等)

    • 因此,您在使用 IN 运算符方面走在了正确的轨道上,但是,您不能在 SQL 查询中直接附加 $match1$match2,因为它们仍然是数组。
    • 您必须将它们转换为逗号分隔的字符串并为每个字符串添加单引号,因为您的 classAclassB 是 DB 表中的字符串列。

    代码:

    <?php
    
    
    $match1 = array('A','B');
    $match2 = array('A','B');
    
    $match1_values = implode(",",array_map("addQuotes",$match1));
    $match2_values = implode(",",array_map("addQuotes",$match2));
    
    $sql = "SELECT classA, classB, value FROM data_table WHERE classA IN ($match1_values) AND classB IN ($match2_values)";
    
    echo $sql;
    
    function addQuotes($each_class_value){
        return "'".$each_class_value."'";
    }
    

    更新:

    你可以替换

    for($i = 0; $i < count($arr); $i++){
            for ($j = 0; $j < count($arr); $j++){
                // make array of class combinations
                $query_array[] = array('classA' => $arr[$i], 'classB' => $arr[$j]);
            }
        }
        // get arrays of pairs to request
        $match1 = array_column($query_array, 'classA');
        $match2 = array_column($query_array, 'classB');
    

    <?php
    
    $match_values = implode(",",array_map("addQuotes",$arr));
    
    $sql = "SELECT classA, classB, value FROM data_table WHERE classA IN ($match_values) AND classB IN ($match_values)";
    
    echo $sql;
    
    function addQuotes($each_class_value){
        return "'".$each_class_value."'";
    }
    

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 2013-05-02
    • 1970-01-01
    相关资源
    最近更新 更多