【问题标题】:Running MySQL queries inside a loop在循环中运行 MySQL 查询
【发布时间】:2015-10-13 12:31:18
【问题描述】:

我想在一个循环中运行多个 mysql 查询。也许这是错误的方法,但这就是我问的原因。

例子:

一个用户提交了一个用户输入数组,我想通过它循环执行多个 mysql 查询。如果我对 ID 进行硬编码,它可以工作,但如果我将 ID 设置为 VAR,它就不行。使用 VAR 时,它总是显示最后一个条目的结果。

最好的,蒂姆

        if(isset($_POST['list'])){ 
            $list=$_POST['list']; 
            $list_arr=explode(PHP_EOL, $list);
            $list_arr_len=count($list_arr);

            for ($i=0; $i < $list_arr_len; $i++) { 
            echo $list_arr[$i]."<br>";
            $result = mysqli_query($con,"SELECT col FROM table where id='$list_arr[$i]'");
            $row=mysqli_fetch_array($result,MYSQLI_NUM);
            echo $row[0]."<br>";


            }
                mysqli_close($con); 
        }

【问题讨论】:

  • 不要像那样循环它,而是尝试使用where id IN(" . implode(',', $list_arr) . " ) ");,你的ID是整数还是字符?
  • 到目前为止,谢谢,我的用户输入是一个字符串。我已经考虑过使用 IN 但我必须做的不仅仅是从数据库中获取,所以使用循环会很好。

标签: php mysql loops


【解决方案1】:

我认为这会奏效:

$result = mysqli_query($con,"SELECT col FROM table where id=".mysqli_real_escape_string($list_arr[$i])."");

【讨论】:

    【解决方案2】:

    您可以像这样在一个查询中完成:

    if(!empty($_POST['list'])){ 
                $list=$_POST['list']; 
                $list_arr=explode(PHP_EOL, $list);
                $list_id=implode("', '", array_map('mysqli_real_escape_string', $list_arr));
    
                $result = mysqli_query($con,"SELECT col FROM table where id IN ('{$list_id}')");
                while($row=mysqli_fetch_array($result,MYSQLI_NUM)) {
                echo $row[0]."<br>";
    
    
                }
                    mysqli_close($con); 
            }
    

    在此示例中,无论您使用哪种类型的 id 列

    【讨论】:

    • 好的,谢谢,我试过了,但同样的问题,如果我硬编码 IN 语句没有问题,如果我使用 VAR 它不起作用。
    • 更新:我提供了 id1 ','id2 作为用户输入,并使用 $list 作为 VAR,例如:mysqli_query($con,"SELECT col FROM table where id IN ('$list')");没有问题,所以我猜它与 \n 等有关。
    【解决方案3】:

    首先创建一个包含所有 id 的字符串,并在查询中使用 IN(String of Ids) 并将与 id 对应的所有数据存储在一个数组中。

    $stringIds = "";
    for ($i=0; $i < $list_arr_len; $i++) 
    { 
         if (is_null($stringIds))
         {
              $stringIds = '"' . $list_arr[$i] . '"';
         }
         else
         {
              $stringIds .= ',"' . $list_arr[$i] . '"';
         }
    }  
    
    $resulSet = mysqli_query($con, ""SELECT col FROM table where id='?'"");
    while($row = mysqli_fetch_assoc($resulSet))
    {
         mainArray[$row['id']] = $row; 
    }
    

    现在,您可以使用 foreach 循环从数组中获取所有数据,请使用 PDO 来避免 SQL 注入。

    【讨论】:

      【解决方案4】:

      问题是:

      \n \r

      这个 c0de 现在对我有用(也 IN('') 可能是更好的主意):

      if(isset($_POST['list'])){ 
                  $list=$_POST['list']; 
                  //echo $list;
                  $replace = array("\n", "\r");
                  $id = str_replace( $replace, ",", $list);
                  $id_arr = explode(",", $id);
                  $id_arr_len = count($id_arr);
      
                  for ($i=0; $i < $id_arr_len; $i++) { 
                      # code...
                  $result = mysqli_query($con,"SELECT col1,col2 FROM table where id='$id_arr[$i]'");
      
                      while($row = mysqli_fetch_assoc($result)){
                      echo $row['col1'].': ';
                      echo $row['col2'].'<br/>';
                      }
      
                  }
      
              }
      

      【讨论】:

      • 您确定要将未经处理的用户输入传递给您的查询吗?
      • 当然你是对的,但这不是我问题的范围。由于我现在可以工作,因此我可以致力于防止 SQL 注入。另外,这永远不会看到 www。它是供内部使用的。但你当然是对的。
      • 您是否对涉及更少代码、PDO 和准备好的语句的解决方案感兴趣?我很乐意发布它,除非它不是你想要的。
      • 当然,我一直对学习新东西很感兴趣
      【解决方案5】:

      创建PDO对象并将其设置为异常模式

      $dsn = 'mysql:dbname=testdb;host=127.0.0.1';
      $user = 'dbuser';
      $password = 'dbpass';
      
      try
      {
          $pdo = new PDO($dsn, $user, $password);
          $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    
      } 
      catch (PDOException $e) 
      {
          echo 'Connection failed: ' . $e->getMessage();
      }
      

      您正在发布一个逗号分隔的列表(我会发布一个数组,但到底是什么),所以我们将简单地将字符串解析为整数并将其粘贴在 MySQL 的 IN 子句中

      if(isset($_POST['list']))
      { 
          $list = str_replace(["\r", "\n"], "", $_POST['list']);
      
          $numbers = strpos($list, ',') !== false ? explode(",", $list) : (int)$list;
      
          // This can probably bet written nicer, the idea is to have each number explicitly typecast to int so it's safe to stick in a query directly
          // Basically, you want "1,2,3,4,5" without the possibility of having some bad input here
          if(is_array($numbers))
          {
              $numbers = implode(",", array_map(function($number)
                                          {
                                              return (int)$number;
                                          }, $numbers));
          }
      
          // And the nice, one liner, where you query and fetch the records which are now in the array called $records
          $records = $pdo->query(sprintf("SELECT * FROM your_table WHERE id IN(%s)", $numbers))->fetchAll(PDO::FETCH_ASSOC);
      }
      

      注意:我没有测试代码所以不要复制粘贴它,它很可能包含错误。我写的答案是为了说明使用PDO 并轻松检索结果是多么容易,在一个班轮中。

      【讨论】:

      • 非常感谢,我会试试的。干杯,蒂姆
      猜你喜欢
      • 2018-12-14
      • 2015-05-18
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 2019-05-26
      • 2015-02-15
      相关资源
      最近更新 更多