Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何以这种在foreach()循环中运行的所需格式构造数组?_Php_Mysql_Arrays - Fatal编程技术网

Php 如何以这种在foreach()循环中运行的所需格式构造数组?

Php 如何以这种在foreach()循环中运行的所需格式构造数组?,php,mysql,arrays,Php,Mysql,Arrays,在下面的场景中,$communityplayers是社区中人员Id的数组,$noPlayers是该数组的计数 e、 g $communityPlayerIds=[2,5,6] $noPlayers=3 以下功能应执行以下操作: 运行sql查询,查询次数由$noPlayers表示,每次检索不同$communityPlayerId的所需数据 目前,这将创建一个新阵列,玩家24项,每个玩家8项 public function getCommunityForm($communityId, $noPlay

在下面的场景中,$communityplayers是社区中人员Id的数组,$noPlayers是该数组的计数

e、 g

$communityPlayerIds=[2,5,6] $noPlayers=3

以下功能应执行以下操作:

运行sql查询,查询次数由$noPlayers表示,每次检索不同$communityPlayerId的所需数据

目前,这将创建一个新阵列,玩家24项,每个玩家8项

public function getCommunityForm($communityId, $noPlayers, $communityPlayersIds){

    $returnValue = array();
    $i = 0;
    foreach ($communityPlayersIds as $cPI){

        $sql = " SELECT player1_result, player1_name, date , results_id FROM `results` WHERE player1_id = '".$cPI."'  AND community_id = '".$communityId."'  UNION ALL SELECT player2_result, player2_name,date, results_id FROM `results` WHERE player2_id = '".$cPI."' AND community_id = '".$communityId."'  ORDER BY date DESC Limit 8";

        $result = $this->conn->query($sql);

        if (mysqli_num_rows($result) === 0) {
            $returnValue[] = ['status' => "nil"];
        }

        if($result != null && (mysqli_num_rows($result) >= 1)){
            while($row = $result -> fetch_array(MYSQLI_ASSOC)){
              if(!empty($row)){
                  $returnValue['players'][$i] = $row;
                 $i++;

                 }
            }
        }

    }
    return $returnValue;
}
我想要的是返回一个数组,其中有3个单独的数组,每个查询运行1个


如何执行此操作?

使用两个单独的计数器。对查询使用$i计数器,对每个查询的行使用另一个计数器

在我们的代码中,将$i的增量移动到foreach循环的末尾,这样每次通过外部循环时,它只会增加一次

 $i = 0
 foreach ($communityPlayersIds as $cPI){
    $sql = "...";
    // process each query
    $i++;
 }
在foreach循环体中,当处理查询返回的行时,请对行使用另一个计数器。在循环之前初始化,并作为循环中的最后一步递增

并将另一个维度添加到结果数组中

       $rn = 0;
       while($row = $result->fetch_array(MYSQLI_ASSOC)){
          //
          $returnValue['players'][$i][$rn] = ... ;
          rn++;
       }
编辑

正如保罗·斯皮格尔(Paul Spiegel)所指出的,$rn计数器并非绝对必要。使用空方括号对数组赋值将向数组中添加新元素

       while($row = $result->fetch_array(MYSQLI_ASSOC)){
          //
          $returnValue['players'][$i][] = ... ;
       }

我所做的第一件事是简化数据库查询,我至少通过消除第二个查询的联合来提高效率

接下来,我设置了一个。这减少了对数据库重复查询的所有开销。我与mysqli合作已经有几年了,但我相信它应该可以工作,只要您的ID列都是数字。我希望如此,但您的原始代码中有引号。如果它们是字符串,请将iiiii更改为sssss,并认真地重新考虑您的数据库模式

您不需要计数器,因为您已经有了玩家ID,只需将其用作数组索引即可

public function getCommunityForm($communityId, $noPlayers, $communityPlayersIds){
    $sql = " SELECT IF(player1_id=?, player1_result, player2_result) AS result, IF(player1_id=?, player1_name, player2_name) AS name, date, results_id FROM `results` WHERE (player1_id=? OR player2_id=?) AND community_id=? ORDER BY date DESC Limit 8";
    $stmt = $this->conn->prepare($sql);

    foreach ($communityPlayersIds as $cPI) {
        $stmt->bind_param("iiiii", $cPI, $cPI, $cPI, $cPI, $communityId);
        $stmt->execute();
        if ($result = $stmt->get_result()) {
            while($row = $result->fetch_array(MYSQLI_ASSOC)){
                 $returnValue['players'][$cPI][] = $row;
                 }
            }
        }
    }
    return $returnValue;
}
这是免费的PDO版本。我强烈建议你调查一下。它比mysqli更现代,也不那么冗长。您将注意到没有参数绑定,我们使用命名参数,从中获取数组要容易得多

public function getCommunityForm($communityId, $noPlayers, $communityPlayersIds){
    $sql = " SELECT IF(player1_id=:pid, player1_result, player2_result) AS result, IF(player1_id=:pid, player1_name, player2_name) AS name, date, results_id FROM `results` WHERE (player1_id=:pid OR player2_id=:pid) AND community_id=:cid ORDER BY date DESC Limit 8";
    $stmt = $this->conn->prepare($sql);

    foreach ($communityPlayersIds as $cPI) {
        if ($stmt->execute([":pid"=>$cPI, ":cid"=>$communityID])) {
             $returnValue['players'][$cPI] = $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
    }
    return $returnValue;
}

至于数据库模式,在结果表中不应该有播放器名称列。那个表中的名字重复了多少次?如果用户想要更改其名称,该怎么办?相反,您应该有一个player表,然后使用join来获取它们的详细信息。

对MySQL的一个函数调用无法做到这一点。使用..->query。。您总是会得到一个行数组,每个行数组中都有字段。SQL命令UNION只会使表变长,它不会将数组嵌套在彼此内部。你需要进行3次..->查询调用。注意:当你可以简单地“计数”$CommunityPlayerId时,为什么你需要“$noPlayers”?而且你的函数无论如何都不会使用它。如果你想只通过一次查询完成所有操作,那么限制8将非常棘手。你应该有一个单独的玩家列,由结果引用。这叫做数据库规范化,查一查!此外,任何时候在循环中执行查询时,都应该使用准备好的语句。它使事情变得更快,也更安全。不需要$rn:$returnValue['players'][$i][]=$row我已经稍微编辑了这个答案,更改了$returnValue['players'][$cPI][]=$row;至$returnValue[$i][]=$row;如果数组被编号为0,1,2,则我可以更轻松地访问数组的每个部分。虽然我正在努力做到这一点,但我将发布另一个问题。谢谢你的回答,它已经为我构造了数组。你只需使用foreach来迭代数组。