70654
以下のようなコードでテーブルを作成すると図のcccとdddがaaaの下に配置されてしまいます。こちらをbbbの右に並べたいのですがどのようにしたらいいでしょうか？

**HTML**

```

    <table>
    <thead>
    <tr>
        <th>1</th>
        <th>2</th>
        <th>3</th>
        <th>4</th>
    </tr>
    </thead>
            <tr>
                <td rowspan="3">aaa</td>
                        
                <?php foreach ($bbb as $key => $val) { ?>
                                
                   <td>
                      <?=$bbb[$key]; ?>
                   </td>
                        
                                
           　</tr>
                  <?php }?>
                       
                        
                  <?php foreach ($ccc as $key => $val) { ?>
                    <td>
                       <?=$ccc[$key]; ?>
                    </td>
                    </tr>    
                            
                  <?php }?>
                        
                        
                            
                  <tr>
                      <td>
                          <?=$ddd; ?>
                      </td>
                  </tr>
    
```

[![画像の説明をここに入力](https://i.stack.imgur.com/kwdSj.png)](https://i.stack.imgur.com/kwdSj.png)

[補足]  
HTMLでは以下でうまくいくのですが、phpのループが入るとこのような形になりません。下の図のようになってしまい、bbbとcccが横並びになってしまいます。

```

    <table border="3">
      <tr>
        <td rowspan="3">aaa</td>
        <td>bbb</td>
        <td>ccc</td>
        <td rowspan="3">ddd</td>
      </tr>
      <tr>
        <td>bbb</td>
        <td>ccc</td>
      </tr>
      <tr>
        <td>bbb</td>
        <td>ccc</td>
      </tr>
    </table>
    
```

[![画像の説明をここに入力](https://i.stack.imgur.com/KknCo.png)](https://i.stack.imgur.com/KknCo.png)
CC BY-SA 4.0
2020-09-23T12:09:59.617
70631
2020-09-24T03:14:12.313
2020-09-24T01:48:09.440
10088
10088
question
php html css
foreachで連続するセルを横並びにしたい
どういうやり方がいいかは色々ありますが。  
プログラミング的思考を紹介して、そこからコードを提案をします。

要件を確認すると配列を繰り返してテーブル組を行う必要があります。  
そのため、まず正しく観察して繰り返すべき部分を分解しないといけません。

結果のHTMLからbbbやcccの配列が増えたときに繰り返して増えている部分はどこでしょうか？  
それは一目瞭然で２行目以降のtrの部分ですね。

```

      <tr>
        <td>bbb</td>
        <td>ccc</td>
      </tr>
    
```

繰り返すとしたら上記を繰り返す必要があります。

ただし例外的な処理が一つあって  
一行目のtrの部分

```

      <tr>
        <td rowspan="3">aaa</td>
        <td>bbb</td>
        <td>ccc</td>
        <td rowspan="3">ddd</td>
      </tr>
    
```

aaaとdddを入れる必要があります。またrowspanでは要素数分のデータを入れる必要があります。

ではこれらを一旦コードに落とし込めるように一般化しておきます。  
一般化は言語に問わず、アルゴリズムを定義するものになります。

**bbbとcccの配列を繰り返してbbbとcccを含んだtdとtrを出力する  
ただし、一行目はaaaとdddを要素数分のrowspanをつけてtdを出力する**

ではPHPで実装するのですが、  
ここで重要なのは[foreach](https://www.php.net/manual/ja/control-
structures.foreach.php)は一つの配列を繰り返し取り出して処理できますが  
2つの配列を繰り返して取り出して処理はできません。  
つまりここは自前で実装する必要があります。  
とはいえ大体「php foreach 配列
2つ」みたいな検索ワードで[ググれば](https://qiita.com/KOH_TA/items/c69b0fce9da1b114fef9)すぐできてますのでそれを利用させてもらいましょう。

段階的にまずは例外のない処理を記述してから、後付で例外処理を記述するほうが私は好きなのでそういう書き方をします。

```

    <table>
      <thead>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
        </tr>
      </thead>
      <?php foreach (array_map(null, $bbb, $ccc) as [$bbb_val, $ccc_val]) { /*繰り返す処理*/ ?>
        <tr>
          <td>
            <?=$bbb_val; /*bbbを出力する*/ ?>
          </td>
          <td>
            <?=$ccc_val; /*cccを出力する*/ ?>
          </td>
        </tr>
      <?php } ?>
    </table>
    
```

次に例外となるaaaとdddを出力する処理をコードに書きます。

```

    <table>
      <thead>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
        </tr>
      </thead>
      <?php $now_row = 0; /* 今の行数が何行目かだけ把握するための変数*/ ?>
      <?php $row_span_num = count($bbb); /*全体で何行あるのか把握してrow_spanで出力するデータ */ ?>
      <?php foreach (array_map(null, $bbb, $ccc) as [$bbb_val, $ccc_val]) { /*繰り返す処理*/ ?>
        <?php $now_row++; /*今の行数をインクリメント*/ ?>
        <tr>
          <?php if ($now_row == 1) { /*一行目だったらaaaを出力する処理に入る*/ ?>
            <td rowspan="<?=$row_span_num; /*rowspanに入れる全行数を出力する*/?>">
              <?=$aaa; ?>
            </td>
          <?php } ?>
          <td>
            <?=$bbb_val; /*bbbを出力する*/ ?>
          </td>
          <td>
            <?=$ccc_val; /*cccを出力する*/ ?>
          </td>
          <?php if ($now_row == 1) { /*一行目だったらdddを出力する処理に入る*/ ?>
            <td rowspan="<?=$row_span_num; /*rowspanに入れる全行数を出力する*/ ?>">
              <?=$ddd; ?>
            </td>
          <?php } ?>
        </tr>
      <?php } ?>
    </table>
    
```

あとはデバックするのですが、今回は省略させていただきます。  
デバックでは実際には$bbbや$cccが実際に取りうる値を想定しながら動かしてみて、想定通りに動くかどうか検証してみましょう。
CC BY-SA 4.0
2020-09-24T03:08:53.300
70654
2020-09-24T03:08:53.300
22665
70631
answer
色々な方法がありますが、今回は、１つのloopで回す必要があり以下のスクリプトのようになります。  
前提：配列は同じ属性のindexであること。

```

        <table>
    <?php
                    $count = 0;
                    $b = array('b1','b2','b3');
                    $c = array('c1','c2','c3');
                    foreach($b as $index=>$b_data){
                        $c_data = $c[$index];
                        if ( $count == 0 ) {
            $pattern = <<<eot
                  <tr>
                    <td rowspan="3">aaa</td>
                    <td>{$b_data}</td>
                    <td>{$c_data}</td>
                    <td rowspan="3">ddd</td>
                  </tr>
        eot;
                
                        } else {
            $pattern = <<<eot
                  <tr>
                    <td>{$b_data}</td>
                    <td>{$c_data}</td>
                  </tr>
        eot;
                
                        }
                        echo $pattern;
                        $count++;
                    }
        ?>
        </table>
    
```
CC BY-SA 4.0
2020-09-24T03:14:12.313
70655
2020-09-24T03:14:12.313
22793
70631
answer