【问题标题】:Fetch multiple rows in mysql single query in php with different id在具有不同ID的php中获取mysql单个查询中的多行
【发布时间】:2018-02-17 07:53:25
【问题描述】:

我有不同的 id,我从用户那里获取这些 id 的值

$id=array();
$id[0]=$_GET["id0"];
$id[1]=$_GET["id1"];
$id[2]=$_GET["id2"];

现在要从数据库中获取数据,我正在使用以下查询:

for($j=0;$j<count($id);$j++)
{
  $res=mysql_query("SELECT * FROM mutable WHERE id='$id[$j]'")
  while($row=mysql_fetch_array($res))
  {
     $row[]=array("email"=>$row[2],"name"=>$row[3],"address"=>$row[5]);
     echo JSON_encode($row);
  }
}

现在我使用 for 循环从这个查询中得到正确的结果,但结果不是正确的 JSON 格式,有没有办法更有效地做到这一点,并在 JSON 数组和 JSON 对象格式中获得正确的结果

【问题讨论】:

  • 抛弃那些旧的mysql_ 函数。出于安全原因,使用带有占位符的 mysqli 准备好的语句。 $result 不存在。
  • 对不起它的 JSON_encode($row);

标签: php mysql json database


【解决方案1】:

json_encode() 放在循环之外。

让我们对事物进行现代化和改进......

*不幸的是,使用IN 子句的准备好的语句会受到卷积的影响。 pdo 不会受到同样的影响。

代码:(未经测试)

if(isset($_GET['id0'],$_GET['id1'],$_GET['id2'])){
    $params=[$_GET['id0'],$_GET['id1'],$_GET['id2']];  // array of ids (validation/filtering can be done here)
    $count=count($params);  // number of ids
    $csph=implode(',',array_fill(0,$count,'?'));  // comma-separated placeholders
    $query="SELECT * FROM mutable WHERE id IN ($csph)";

    $stmt=$mysqli->prepare($query);  // for security reasons

    array_unshift($params,str_repeat('s',$count));  // prepend the type values string
    $ref=[];  // add references
    foreach($params as $i=>$v){
        $ref[$i]=&$params[$i];  // pass by reference as required/advised by the manual
    }
    call_user_func_array([$stmt,'bind_param'],$ref);    

    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_array(MYSQLI_NUM))
        $rows=["email"=>$row[2],"name"=>$row[3],"address"=>$row[5]];
    }
    $stmt->close();
    echo json_encode($rows);
}

【讨论】:

  • 您在for 循环之后编写了json_encode()?在您的问题中发布您的 不正确 json 并向我们展示您的预期结果。
  • 如果您不知道用户可以发送多少id 值,那么您的表单需要改进。 id 输入字段上的名称属性应如下所示:name='id[]',然后您的 $_GET['id'] 将是一个可以处理的 id 数组。
【解决方案2】:

三件事:

  1. 总是、总是总是在处理不受信任的(即$_GET)输入时使用prepared statements 和绑定参数。去做吧。

  2. 关于你的JSON问题,你只需要运行一次json_encode

    $results = [];
    for($j=0;$j<count($id);$j++) {
        ...
        while($row=mysql_fetch_array($res)) {
            results[] = ...
        }
    }
    json_encode( $results );
    
  3. 使用单个 SQL 语句,因为您要收集已知数量的 ID:

    $dbh = new PDO($dsn, $user, $password);
    $sql = "SELECT * FROM mutable WHERE id IN (?, ?, ?)";
    $sth = $dbh->prepare( $sql );
    foreach ( $sth->execute( [$_GET['id0'], $_GET['id1'], $_GET['id2']] ) as $row ) {
        ...
    

    这比多次往返数据库更有效。对于这种人为的情况,这可能无关紧要,但从长远来看,现在养成良好的习惯将对您有所帮助。

【讨论】:

  • 我很确定 OP 不知道 $dsn 是什么意思 ;)
  • @Akintunde007 公平。另一方面,OP 成功连接了mysql* 函数,并希望谷歌搜索不熟悉的细节。不过,我不太关心这部分问题。
  • @hunteke 如果我不知道我从用户那里获得的 ID 数量,假设他第一次发送 1 个值,其他时间可能是 3,4 或 5 个值,我会设法收集这些不同的ID,但是如何在查询中使用这些不同的ID---
  • 在这种情况下,要么退回到您已经知道的“一次一个”方法,要么建立$sql 字符串。例如,假设您有 $ids = ["1", "3", "5"] 作为用户传递的 ID。然后您可以将绑定部分构建为:$bind = implode(',', array_fill(0,count($ids),'?'));,然后将您的 sql 构建为$sql = "... id IN ($bind)"。然后最后执行$sth-&gt;execute( $ids )
【解决方案3】:

你用错了$row,在循环外声明数组变量

    $json_response = array();
    for($j=0;$j<count($id);$j++) {
        $res=mysql_query("SELECT * FROM mutable WHERE id='$id[$j]'")
        while($row=mysql_fetch_array($res)) {
            $json_response[]=array("email"=>$row[2],"name"=>$row[3],"address"=>$row[5]);
            echo json_encode($json_response); // not good to echo here
        }
    }
    // echo json_encode($json_response); // ideally echo should be here

【讨论】:

    猜你喜欢
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    相关资源
    最近更新 更多