PHPのforeach文は、配列の要素を先頭から一つずつ取り出して処理するための構文です。商品の一覧を表示したり、点数を合計したりするときに使います。
for文と違い、要素数やインデックスを自分で管理する必要がありません。配列の基本が不安な方は、先にPHPの配列を確認してください。
foreach文の基本構文
値だけを取り出す場合は、次の形で書きます。
<?php
$fruits = ["りんご", "バナナ", "みかん"];
foreach ($fruits as $fruit) {
echo $fruit . PHP_EOL;
}
実行結果は次のとおりです。
りんご
バナナ
みかん
繰り返すたびに、現在の要素が$fruitへ代入されます。変数名は、配列の複数形と要素の単数形を使うと意味が伝わりやすくなります。
キーと値を取り出す
$key => $valueの形を使うと、配列のキーと値を同時に取り出せます。
<?php
$prices = [
"りんご" => 150,
"バナナ" => 120,
"みかん" => 100,
];
foreach ($prices as $name => $price) {
echo $name . "は" . $price . "円です" . PHP_EOL;
}
実行結果です。
りんごは150円です
バナナは120円です
みかんは100円です
合計や件数を計算する
繰り返しの前に合計用の変数を用意し、各要素を加算します。
<?php
$scores = [80, 75, 90];
$total = 0;
foreach ($scores as $score) {
$total += $score;
}
echo "合計: " . $total . PHP_EOL;
echo "平均: " . ($total / count($scores)) . PHP_EOL;
空の配列ではcount($scores)が0になり、割り算ができません。平均を求める場合は、配列が空でないことも確認しましょう。
<?php
$scores = [];
if ($scores === []) {
echo "点数がありません";
} else {
$average = array_sum($scores) / count($scores);
echo $average;
}
多次元配列を処理する
配列の中に配列がある場合も、foreachで一件ずつ取り出せます。
<?php
$users = [
["name" => "田中", "age" => 20],
["name" => "佐藤", "age" => 25],
];
foreach ($users as $user) {
echo $user["name"] . "さん(" . $user["age"] . "歳)" . PHP_EOL;
}
HTMLの一覧を作る
Webページでは、HTMLの途中でPHPを開閉すると一覧構造を読みやすく書けます。画面へ出す文字列はhtmlspecialchars()でエスケープします。
<?php
$fruits = ["りんご", "バナナ", "みかん"];
?>
<ul>
<?php foreach ($fruits as $fruit): ?>
<li><?= htmlspecialchars($fruit, ENT_QUOTES, "UTF-8") ?></li>
<?php endforeach; ?>
</ul>
foreach: ... endforeach;は、通常の中括弧と同じ働きをする別構文です。HTMLと混ぜる場面では、開始と終了が見つけやすくなります。
breakとcontinueを組み合わせる
breakは繰り返しを終了し、continueは現在の回だけを飛ばします。
<?php
$numbers = [3, -1, 8, 0, 12];
foreach ($numbers as $number) {
if ($number < 0) {
continue; // 負の数は処理しない
}
if ($number === 0) {
break; // 0が来たら終了する
}
echo $number . PHP_EOL;
}
この例では3を表示し、-1を飛ばし、8を表示したあと、0で終了します。詳しくはbreakとcontinueの使い方も参照してください。
要素を書き換えるときは参照を使う
値の前に&を付けると、元の配列要素を直接変更できます。
<?php
$prices = [100, 200, 300];
foreach ($prices as &$price) {
$price = (int) ($price * 1.1);
}
unset($price); // 参照を必ず解除する
print_r($prices);
参照付きforeachのあとも、$priceは最後の要素を参照し続けます。思わぬ変更を防ぐため、直後にunset($price)を書いて参照を解除してください。
for文とforeach文の使い分け
| 構文 | 向いている処理 |
|---|---|
foreach | 配列や反復可能なオブジェクトを一件ずつ処理する |
for | 回数や数値インデックスを自分で制御する |
while | 条件を満たす間、回数が決まっていない処理を続ける |
配列を順番に読むだけなら、通常はforeachが最も読みやすい選択です。
よくある間違い
- 配列でない値や未定義変数を
foreachへ渡す - 連想配列で数値インデックスがあると思い込む
- 参照付きループのあとに
unset()を書かない - HTMLへ値を出すときにエスケープしない
練習問題
商品名と価格を持つ配列から、200円以上の商品だけを「商品名: 価格円」の形式で表示してください。
解答例を見る
<?php
$products = [
["name" => "ノート", "price" => 180],
["name" => "ペン", "price" => 250],
["name" => "ファイル", "price" => 320],
];
foreach ($products as $product) {
if ($product["price"] < 200) {
continue;
}
echo $product["name"] . ": " . $product["price"] . "円" . PHP_EOL;
}
まとめ
foreach ($items as $item)で値を一つずつ取り出すforeach ($items as $key => $value)でキーも取得する- 参照で変更したあとは
unset()で参照を解除する - 画面へ値を出すときはエスケープする
条件を使った処理が不安な場合は、条件分岐の書き方も確認してください。
コメント