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