phpのforeach文を使って4項目ずつDivタグに囲んで繰り返し表示出来るようにしたいのですが、思うように動かないため質問しました。
現在、データベースに登録された名前を下記の書き方ですべて表示出来ています。
php
1<?php 2foreach ($records as $record) { ?> 3 <?php echo $record['name'] ?> 4 <?php } ?> 5
現状だとそのまま9人目、8人目、7人目・・・といったように表示されているため、
データベースに登録された名前をforeachで繰り返し4人ごとdivで囲んで表示したいと考えています。
色々やったのですが、9人目9人目9人目9人目と表示されてしまったり、エラーが出てしまったり。。
html
1<div> 2 9人目 3</div> 4 5 <div> 68人目 77人目 86人目 95人目 10</div> 11<div> 124人目 133人目 142人目 151人目 16</div> 17 18 19下記のコードでは同じものが4つずつ表示されてしまいました。 20また、エラーが出てしまったコードについては、書いては消しを繰り返したため 21残ってないです。。 22```php 23<?php 24foreach ($records as $record) { ?> 25<div> 26<?php echo $record['name'] ?> 27<?php echo $record['name'] ?> 28<?php echo $record['name'] ?> 29<?php echo $record['name'] ?> 30</div> 31 <?php } ?>
回答のほど宜しくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/09/01 23:31
回答5件
0
foreach 文を使ってデータベースから取得した結果を出力するのは出来ているので、そこに4つ区切りに <div>, </div> を挿入するようなコードを加えればよいと思います。
説明のため、まず表示するだけのサンプルコードを示します:
php
1<?php 2// 表示するだけのコード 3$records = [ 4 ['name' => '9人目'], ['name' => '8人目'], ['name' => '7人目'], ['name' => '6人目'], ['name' => '5人目'],['name' => '4人目'], ['name' => '3人目'], ['name' => '2人目'], ['name' => '1人目'] 5]; 6?> 7<?php foreach ($records as $i => $record): ?> 8 <?= htmlspecialchars($record['name']).PHP_EOL ?> 9<?php endforeach; ?>
// 結果 9人目 8人目 7人目 6人目 5人目 4人目 3人目 2人目 1人目
で、ここに4つおきに <div>, </div> を挿入するわけですが、方法を考えるのはコーディングというより、どちらかというと算数と頭の体操です。
まず先頭から4つおきに <div> を入れるなら、4の倍数(4n)になったときに <div> を出力すればよさそうです。つまり判定式は $i % 4 === 0
です。また </div> は 4n-1 になったときに出力します。判定式は $i % 4 === 3
です。ただこのままですと要素数が4の倍数ではない場合にタグが閉じられないため、最後にも閉じタグを挿入するのを忘れないでください。
結果的にこんなコードになります:
php
1<?php foreach ($records as $i => $record): ?> 2<?= $i % 4 === 0 ? '<div>'.PHP_EOL : null ?> 3 <?= htmlspecialchars($record['name']).PHP_EOL ?> 4<?= $i % 4 === 3 || $i === count($records) - 1 ?'</div>'.PHP_EOL : null ?> 5<?php endforeach; ?>
// 結果 <div> 9人目 8人目 7人目 6人目 </div> <div> 5人目 4人目 3人目 2人目 </div> <div> 1人目 </div>
あとは同じ要領で、今度は末尾から4つ区切りを行う方法をご自身で考えてみてください。count($records)-$i
で残りの要素数を把握できるので、役に立ちそうです。
ちなみにデータベース(MySQL, PostgreSQL)やデータベースドライバの設定によっては、$i や count() が効かない場合があります。そのときは自前でカウントを行って下さい。
カウンター($i)が使えない場合は $i = 0;
と初期化しつつ、foreachのループ内で $i++;
と手動カウントすればOKです。
count($records)
が使えない場合は、データベースから取得した全結果を一度配列にいれて count() してください。
投稿2017/09/02 00:37
編集2017/09/02 01:47総合スコア3095
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/09/02 02:47
0
miyahan さんの回答が好きですけど、count がループの中に入ってるんで、外出にしたかったのと、外に出したんならなんとなく while じゃないかなぁと思って作ってみました。
php
1<?php 2$records = [ 3 [ 4 'name' => '9人目', 5 'age' => 20, 6 ], 7 [ 8 'name' => '8人目', 9 'age' => 21, 10 ], 11 [ 12 'name' => '7人目', 13 'age' => 22, 14 ], 15 [ 16 'name' => '6人目', 17 'age' => 23, 18 ], 19 [ 20 'name' => '5人目', 21 'age' => 24, 22 ], 23 [ 24 'name' => '4人目', 25 'age' => 25, 26 ], 27 [ 28 'name' => '3人目', 29 'age' => 26, 30 ], 31 [ 32 'name' => '2人目', 33 'age' => 27, 34 ], 35 [ 36 'name' => '1人目', 37 'age' => 28, 38 ], 39 ]; 40 $count = count($records); 41 $i = $count; 42?> 43<?php while ($i > 0):?> 44<?= $i % 4 === 0 || $i === $count ? '<div>'.PHP_EOL : null ?> 45<?= $i % 4 . ':' . htmlspecialchars(each($records)['value']['name']).PHP_EOL ?> 46<?= $i % 4 === 1 ?'</div>'.PHP_EOL : null ?> 47<?php $i -= 1 ?> 48<?php endwhile ?>
結果、each とか使って、あんまりきれいじゃないw
投稿2017/09/02 02:15
退会済みユーザー
総合スコア0
0
array_chunk()
で配列をあらかじめ4つの要素に分割してから、for()
で<div>
タグを出力する外側に対応する配列をループします。そして、各4つの要素に対応する連想配列をforeach()
で出力します。
下記コードの最下部コメントの「出力:」部分がarray_chunk()
した連想配列です。
php
1// $records連想配列 2$records = array( 3 array('name' => '1人目'), 4 array('name' => '2人目'), 5 array('name' => '3人目'), 6 array('name' => '4人目'), 7 array('name' => '5人目'), 8 array('name' => '6人目'), 9 array('name' => '7人目'), 10 array('name' => '8人目'), 11 array('name' => '9人目'), 12); 13 14// $records配列を4つの要素で分割(インデックスはそのまま) 15$array = array_chunk($records, 4, true); 16 17for ($i=0; $i<count($array); $i++) { 18 echo "<div>\n"; 19 foreach ($array[$i] as $record) { 20 echo "\t".$record['name']."\n"; 21 } 22 echo "</div>\n"; 23} 24 25echo '<pre>'; 26echo '$array : '; 27print_r($array); 28echo "\n"; 29echo '</pre>'; 30 31// 出力: 32// $recordsのインデックスを保持 33// 34// $array = array( 35// array( 36// '0' => array('name' => '1人目'), 37// '1' => array('name' => '2人目'), 38// '2' => array('name' => '3人目'), 39// '3' => array('name' => '4人目'), 40// ), 41// array( 42// '4' => array('name' => '5人目'), 43// '5' => array('name' => '6人目'), 44// '6' => array('name' => '7人目'), 45// '7' => array('name' => '8人目'), 46// ), 47// array( 48// '8' => array('name' => '9人目'), 49// ), 50// );
array_walk_recursive()
を使った下記のサンプルコードでも上記と同じ結果が得られます。通常はforeach()
を使ったほうがパフォーマンスが高いですが、メンテナンス性も考慮してどちらにするか決めてください。配列の要素数が大きくなるとパフォーマンスが非常に重要になります。
php
1// $records連想配列 2$records = array( 3 array('name' => '1人目'), 4 array('name' => '2人目'), 5 array('name' => '3人目'), 6 array('name' => '4人目'), 7 array('name' => '5人目'), 8 array('name' => '6人目'), 9 array('name' => '7人目'), 10 array('name' => '8人目'), 11 array('name' => '9人目'), 12); 13 14// $records配列を4つの要素で分割(インデックスはそのまま) 15$array = array_chunk($records, 4, true); 16 17for ($i=0; $i<count($array); $i++) { 18 echo "<div>\n"; 19 array_walk_recursive($array[$i], function ($value, $key) { 20 echo is_array($value) ?: "\t".$value."\n"; 21 }); 22 echo "</div>\n"; 23}
投稿2017/09/02 01:29
総合スコア1652
0
ベストアンサー
php
1foreach ($records as $record) {
から始まるループの中では、$record
の値は一緒です。一緒でなかったら困りますよね。
ループ内の処理が終わって、次のループに入ったときに $record
の中身が変わります。
何度 echo
しても「9人目」になるのはそういう理由です。
次々にレコードにアクセスするには、foreach ($records as $record)
のループはグルグル回しさなければなりません。数レコードずつまとめて表示するには、(1) レコードのループを回しながら、条件に応じてまとめるタグを出力する、(2) まとめて出力する用の多重配列にレコードを格納していって、あとでまとめて出力する、などの方法があると思います。
(1) のケースの例です。
php
1$records_per_div = 4; 2$count = 0; 3foreach ($records as $record) : 4 if ($count % $records_per_div == 0) : // 4 行ごとに div を始める 5 if ($count > 0) : // 最初以外は今までの div を閉じる 6 ?> 7</div> 8<?php endif; ?> 9<div> 10<?php endif; ?> 11<?php echo $record['name'] . "\n"; ?> 12<?php $count++; ?> 13<?php endforeach; ?> 14<?php if ($count > 0) : // 最後の div を閉じる ?> 15</div> 16<?php endif; ?>
(2) のケースです。div タグでまとめるものを section
と名付けてあります。
php
1<?php 2$sections = array(); 3$records_per_div = 4; 4$index = 0; 5$section_no = 0; 6foreach ($records as $record) { 7 if ($index == 0) { 8 $section_no++; 9 $sections[$section_no] = array(); 10 } 11 $sections[$section_no][$index] = $record['name']; 12 $index++; 13 if ($index >= $records_per_div) $index = 0; 14} 15 16foreach ($sections as $section) : 17?> 18<div> 19<?php 20 foreach ($section as $name) { 21 echo $name."\n"; 22 } 23?> 24</div> 25<?php endforeach;
投稿2017/09/02 00:30
総合スコア2468
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/09/02 00:40
0
HTML の文法を確認するって意味では、Tomak さんのものをベースにするのが良いかも。
<div></div>の関係が分かりやすいです。 ```php <?php $records = [ [ 'name' => '9人目', 'age' => 20, ], [ 'name' => '8人目', 'age' => 21, ], [ 'name' => '7人目', 'age' => 22, ], [ 'name' => '6人目', 'age' => 23, ], [ 'name' => '5人目', 'age' => 24, ], [ 'name' => '4人目', 'age' => 25, ], [ 'name' => '3人目', 'age' => 26, ], [ 'name' => '2人目', 'age' => 27, ], [ 'name' => '1人目', 'age' => 28, ], ]; $records = array_reverse($records); $array = array_chunk($records, 4, true); $count = count($array); ?> <?php for ($i=$count-1; $i >= 0; --$i):?> <div> <?php $array[$i] = array_reverse($array[$i]);?> <?php foreach ($array[$i] as $record){ echo "\t".$record['name']."\n"; } ?> </div> <?php endfor ?> ```投稿2017/09/02 02:32
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。