HTML table 在 php foreach 循环中,仅当元素等于 table 列标题名称时才填充单元格数据

HTML table in php foreach loop where the cell data is only populated if an element is equal to the table column head name

我在我的 table 中创建了我的专栏 headers,方法是:

if (count($round) > 0): ?>
<table>
  <thead>
    <tr>
<?php foreach ($round as $colhead): array_map('htmlentities', $colhead); ?>
      <th><?php  echo implode('</th><th>',$colhead); ?></th>
    </tr>
<?php endforeach; endif;
?>
  </thead>

$round 是:

Array
(
    [0] => Array
        (
            [32] => -7
            [31] => -6
            [29] => -5
            [27] => -4
            [23] => -3
            [19] => -2
            [17] => -1
            [0] => 1
            [2] => 2
            [10] => 3
            [14] => 4
            [16] => 5
            [33] => 6
        )

)

这正是我想要的结果,因为 $round 不会总是产生相同数量的列。

我想要在 header 下方的 table 行中的数据只需要包含列 header 名称的那些项目。

假设第 header 列是: | -7 | -6 | -5 | -4 | -3 | -2 | -1 | 1 | 2 | 3 | 4 | 5 | 6 | 基于上面的 foreach 循环。

我使用以下内容填充下一行中的第一列:

<tbody>
    <tr>
      <td>
  <?php foreach ($matches as $match)  {
$firstCharacter = $match['match']['scores_csv'][0];
$lastCharacter = $match['match']['scores_csv'][-1]; 
$id1 = $match['match']['player1_id'];
$id2 = $match['match']['player2_id'];
    if ($match['match']['round'] === -7) 
      echo  "Table: ".$match['match']['player1_votes']."</br>".$participants[$id1]["name"].$participants[$id1]['misc'].": ".$firstCharacter. "</br>".$participants[$id2]["name"].$participants[$id2]['misc'].":".$lastCharacter. "</br>";
  }
  ?>
    </td>
   </tr>
  </tbody>
</table>

虽然它有效,但这只是因为我知道 table 中第一列的 header 是 -7。我想弄清楚如何只显示那些等于我的列 header 的项目,以根据列 header 显示在下一行中,这样我就可以再做一个 foreach 循环来显示我的 table 的剩余部分。所以基本上,我需要做什么而不是上面的 -7?我完全是一片空白。

$match['match']['round'] 等于列 headers。下面是一个小样本 $matches 以防有帮助。

 [{"match":{"id":246811883,"tournament_id":10128202,"state":"complete","player1_id":152239163,"player2_id":152239166,"player1_prereq_match_id":null,"player2_prereq_match_id":null,"player1_is_prereq_match_loser":false,"player2_is_prereq_match_loser":false,"winner_id":152239166,"loser_id":152239163,"started_at":"2021-08-07T01: 59: 51.967+02: 00","created_at":"2021-08-07T01: 59: 51.692+02: 00","updated_at":"2021-08-07T02: 22: 29.417+02: 00","identifier":"A","has_attachment":false,"round":1,"player1_votes":1,"player2_votes":null,"group_id":null,"attachment_count":null,"scheduled_time":null,"location":null,"underway_at":"2021-08-07T02: 05: 31.834+02: 00","optional":false,"rushb_id":null,"completed_at":"2021-08-07T02: 22: 29.455+02: 00","suggested_play_order":null,"forfeited":null,"open_graph_image_file_name":null,"open_graph_image_content_type":null,"open_graph_image_file_size":null,"prerequisite_match_ids_csv":"","scores_csv":"0-2"}},{"match":{"id":246811884,"tournament_id":10128202,"state":"complete","player1_id":152239594,"player2_id":152239168,"player1_prereq_match_id":null,"player2_prereq_match_id":null,"player1_is_prereq_match_loser":false,"player2_is_prereq_match_loser":false,"winner_id":152239594,"loser_id":152239168,"started_at":"2021-08-07T01: 59: 51.984+02: 00","created_at":"2021-08-07T01: 59: 51.698+02: 00","updated_at":"2021-08-07T02: 32: 30.655+02: 00","identifier":"B","has_attachment":false,"round":1,"player1_votes":2,"player2_votes":null,"group_id":null,"attachment_count":null,"scheduled_time":null,"location":null,"underway_at":"2021-08-07T02: 05: 23.667+02: 00","optional":false,"rushb_id":null,"completed_at":"2021-08-07T02: 32: 30.690+02: 00","suggested_play_order":null,"forfeited":null,"open_graph_image_file_name":null,"open_graph_image_content_type":null,"open_graph_image_file_size":null,"prerequisite_match_ids_csv":"","scores_csv":"2-1"}}]

我尝试使用以下方法重新索引数组:

$matchesa = array_column($matches, 'match');
$matchesa = array_column($matchesa, null, 'round');

foreach ( $matches as $match )  {
            $id1 = $match['match']['round'];
 {
        echo $matchesa[$id1]['round'].PHP_EOL;
    }
  }

期望的输出是这样的:

前面的一些评论:

您的 $round 数组只有一个元素,但您有一个 foreach 语句迭代“所有”元素 ...

foreach ($round as $colhead): array_map('htmlentities', $colhead);

... 这在语义上没有多大意义,因为 table 不应该有多个 headers。然后您在 $colhead 列表上调用 array_map,但结果不会保存并在以后使用。此外,由于这些值是整数,因此甚至没有理由将 htmlentities 函数应用于这些值。稍后,当您放置名称等实体时,此功能可能会派上用场。

以下代码在轮数和 $matches 数组中可以找到该轮数的索引之间构建一个映射。然后处理变得大大简化。仅用于演示目的:

  1. 我只为每个匹配输出 player1_id 值,这样处理的细节就不会丢失,为了简单起见,我将这个值设置为与轮数相同。
  2. 如果没有找到匹配的轮次,table 列只填充 <br>
  3. 同样为了简单起见,我定义了 $round 数组以包含一个元素,一个包含值 [-1, -3, -5] 的列表,而 $matches 数组将只有两个 table 行的数据.第一行是轮数 -1 和 -5(-3 将丢失),第二行将包含所有三个轮数。
<?php
$round = [[-1, -3, -5]];

$match0 = [];
$match0[] = Array('match' => Array('round' => 2, 'player1_id' => 2));
$match0[] = Array('match' => Array('round' => 1, 'player1_id' => 1));
$match0[] = Array('match' => Array('round' => 3, 'player1_id' => 3));
$match0[] = Array('match' => Array('round' => -1, 'player1_id' => -1));
$match0[] = Array('match' => Array('round' => -4, 'player1_id' => -4));
$match0[] = Array('match' => Array('round' => -5, 'player1_id' => -5));
$match0[] = Array('match' => Array('round' => -6, 'player1_id' => -6));

$match1 = [];
$match1[] = Array('match' => Array('round' => -7, 'player1_id' => -7));
$match1[] = Array('match' => Array('round' => -1, 'player1_id' => -1));
$match1[] = Array('match' => Array('round' => -2, 'player1_id' => -2));
$match1[] = Array('match' => Array('round' => -3, 'player1_id' => -3));
$match1[] = Array('match' => Array('round' => -8, 'player1_id' => -8));
$match1[] = Array('match' => Array('round' => 9, 'player1_id' => 9));
$match1[] = Array('match' => Array('round' => -5, 'player1_id' => -5));

$matches = [$match0, $match1];


if (count($round) > 0):
    $round0 = $round[0];
?>
<table>
  <thead>
    <tr>
<?php
    foreach($round0 as $hdr):
?>
      <th><?= $hdr ?></th>
<?php
    endforeach;
?>
    </tr>
  </thead>
  <tbody>
<?php
    foreach ($matches as $match):
        // create mapping between round number and index into $matches:
        $index_map = [];
        $l = count($match);
        for ($i = 0; $i < $l; $i++):
            $matchRound = $match[$i]['match']['round'];
            $index_map[$matchRound] = $i;
        endfor;
?>
    <tr>
<?php
        foreach($round0 as $matchRound):
            if (!array_key_exists($matchRound, $index_map)):
?>
      <th><br></th>
<?php
            else:
                $theMatch = $match[$index_map[$matchRound]]['match']
?>
      <th><?= $theMatch['player1_id'] ?></th>
<?php
            endif;
        endforeach;
    endforeach;
?>
    </tr>
  </tbody>
</table>
<?php
endif;
?>

输出:

<table>
  <thead>
    <tr>
      <th>-1</th>
      <th>-3</th>
      <th>-5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>-1</th>
      <th><br></th>
      <th>-5</th>
    <tr>
      <th>-1</th>
      <th>-3</th>
      <th>-5</th>
    </tr>
  </tbody>
</table>

您已经在 $colhead 中拥有所有 header 列。

因此,您可以像这样迭代列:

foreach ($matches as $match) {
    $colindex = 0;
    for ($colindex = 0; $colindex < count($colhead), $colindex++) {
        if ($match['match']['round'] === $colhead[$colindex]) {
            //your cell template here
        }
    }
}

您可以使用字典来存储基于回合的所有匹配项:

<?php

/*#########SAMPLE DATA########*/

$matches = <<<MATCHES
[{"match":{"id":246811883,"tournament_id":10128202,"state":"complete","player1_id":152239163,"player2_id":152239166,"player1_prereq_match_id":null,"player2_prereq_match_id":null,"player1_is_prereq_match_loser":false,"player2_is_prereq_match_loser":false,"winner_id":152239166,"loser_id":152239163,"started_at":"2021-08-07T01: 59: 51.967+02: 00","created_at":"2021-08-07T01: 59: 51.692+02: 00","updated_at":"2021-08-07T02: 22: 29.417+02: 00","identifier":"A","has_attachment":false,"round":1,"player1_votes":1,"player2_votes":null,"group_id":null,"attachment_count":null,"scheduled_time":null,"location":null,"underway_at":"2021-08-07T02: 05: 31.834+02: 00","optional":false,"rushb_id":null,"completed_at":"2021-08-07T02: 22: 29.455+02: 00","suggested_play_order":null,"forfeited":null,"open_graph_image_file_name":null,"open_graph_image_content_type":null,"open_graph_image_file_size":null,"prerequisite_match_ids_csv":"","scores_csv":"0-2"}},{"match":{"id":246811884,"tournament_id":10128202,"state":"complete","player1_id":152239594,"player2_id":152239168,"player1_prereq_match_id":null,"player2_prereq_match_id":null,"player1_is_prereq_match_loser":false,"player2_is_prereq_match_loser":false,"winner_id":152239594,"loser_id":152239168,"started_at":"2021-08-07T01: 59: 51.984+02: 00","created_at":"2021-08-07T01: 59: 51.698+02: 00","updated_at":"2021-08-07T02: 32: 30.655+02: 00","identifier":"B","has_attachment":false,"round":1,"player1_votes":2,"player2_votes":null,"group_id":null,"attachment_count":null,"scheduled_time":null,"location":null,"underway_at":"2021-08-07T02: 05: 23.667+02: 00","optional":false,"rushb_id":null,"completed_at":"2021-08-07T02: 32: 30.690+02: 00","suggested_play_order":null,"forfeited":null,"open_graph_image_file_name":null,"open_graph_image_content_type":null,"open_graph_image_file_size":null,"prerequisite_match_ids_csv":"","scores_csv":"2-1"}}]
MATCHES;

$round = <<<ROUND
[-7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6]
ROUND;

$matches = json_decode($matches, true);
$round = json_decode($round);


/*###########################*/

//class to define data when we found a match
class MatchInfo {
    public $firstCharacter;
    public $lastCharacter;
    public $player1Votes;
    public $player1Name;
    public $player1Misc;
    public $player2Name;
    public $player2Misc;
}

$tableHeaders = null;
$matchInfoData = [];
//$participants = [...]

if (!empty($round)) { //if we have round
    //get the html for table headers
    $tableHeaders = array_map(function($colHead){
        return "<th>Round: {$colHead}</th>";
    }, $round);
    $tableHeaders = implode("", $tableHeaders);

    //remove item in matches
    while ($match = array_pop($matches)) {
        $targetRound = $match['match']['round'];
        if (!in_array($targetRound, $round)) continue; //skip item if match round is not in our column

        if (!array_key_exists($targetRound, $matchInfoData)) { //if we never look at this round before
            $matchInfoData[$targetRound] = []; //initialize array to hold other match based on the round
        }


        $id1 = $match['match']['player1_id'];
        $id2 = $match['match']['player2_id'];
        //new up and save off the data
        $matchInfo = new MatchInfo();
        $matchInfo->firstCharacter = $match['match']['scores_csv'][0];
        $matchInfo->lastCharacter = $match['match']['scores_csv'][-1];
        $matchInfo->player1Votes = $match['match']['player1_votes'];
        $matchInfo->player1Name = "Player1 Name"; //$participants[$id1]["name"];
        $matchInfo->player1Misc = "Player1 Misc"; //$participants[$id1]["misc"];
        $matchInfo->player2Name = "Player2 Name"; //$participants[$id2]["name"];
        $matchInfo->player2Misc = "Player2 Misc"; // $participants[$id2]["misc"];

        $matchInfoData[$targetRound][] = $matchInfo; //add data to the round...array_push
    }

}

//if no matches found exit
if (empty($matchInfoData)) {
    echo "No match info";
    exit;
}

$tableData = '';
//now we loop through all the array to be sure its the same order as the ths
foreach ($round as $td) {
    $columnHtml = '';
    if (array_key_exists($td, $matchInfoData)) { //if what we stored contains the targeted column
        //create a td html
        $dataHtmlArray = array_map(function(MatchInfo $curItem){
            return <<<ITEMDATA
    <div class="match-info">
        Table: {$curItem->player1Votes} <br/>
        {$curItem->player1Name} {$curItem->player1Misc} {$curItem->firstCharacter} <br/>
        {$curItem->player2Name} {$curItem->player2Misc} {$curItem->lastCharacter } <br/>
    </div>
ITEMDATA;

        },$matchInfoData[$td]);

        $dataHtml = implode("<br/>", $dataHtmlArray);
        $columnHtml = "<td><div class='match-container'> {$dataHtml} </div></td>";

    }else { //otherwise it needs a blank td to go to next column
        $columnHtml = "<td></td>";
    }
    $tableData .= $columnHtml;
}

?>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">

<table class="table table-bordered">
    <thead>
    <tr><?php echo $tableHeaders; ?></tr>
    </thead>
    <tbody>
    <tr>
        <?php echo $tableData; ?>
    </tr>

    </tbody>
</table>

<style>
    .match-info {
        border: 1px solid #dadde5;
        padding: 24px;
        border-radius: 4px;
    }
</style>