PHPのforeachは、配列の中身を1つずつ取り出して処理するための構文です。
特に連想配列を扱う場合、foreachを使うと、配列の「キー」と「値」をセットで取り出せます。
ユーザー情報、商品情報、フォームの入力内容、データベースから取得した一覧データなど、Web開発では非常によく使われます。
この記事では、PHPの連想配列とforeachの基本的な使い方から、HTML表示、値の変更、多次元配列の扱い方、実務で注意したいポイントまで詳しく解説します。
連想配列とは
PHPの配列はキーと値でデータを管理する
PHPの配列は、キーと値の組み合わせでデータを管理します。
たとえば、次のような配列があります。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
この配列では、name、age、emailがキーです。
それぞれのキーに対して、次のような値が入っています。
name => 山田太郎
age => 25
email => taro@example.com
このように、意味のあるキーを使って値を管理する配列を、一般的に連想配列と呼びます。
インデックス配列との違い
PHPの配列には、次のようなインデックス配列もあります。
$fruits = ["apple", "banana", "orange"];
これは、内部的には次のような形です。
[
0 => "apple",
1 => "banana",
2 => "orange"
]
インデックス配列では、0、1、2のような数値キーで値を管理します。
一方、連想配列では、次のように文字列キーを使って値を管理することが多いです。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
ただし、厳密に言うと、PHPの配列は「インデックス配列」と「連想配列」という別々の型に分かれているわけではありません。
PHPの配列は1種類で、キーの使い方によって「インデックス配列」や「連想配列」と呼び分けています。
そのため、次のように数値キーと文字列キーを混在させることもできます。
$data = [
0 => "apple",
"name" => "山田太郎",
1 => "banana",
"age" => 25
];
初心者のうちは、数字のキーで管理するものをインデックス配列、名前付きのキーで管理するものを連想配列と考えると理解しやすいです。
foreachの基本構文
値だけを取り出す書き方
foreachで配列の値だけを取り出す場合は、次のように書きます。
foreach ($array as $value) {
// 処理
}
たとえば、次の連想配列を使います。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
値だけを表示する場合は、次のように書けます。
foreach ($user as $value) {
echo $value . "<br>";
}
出力結果は次のようになります。
山田太郎
25
taro@example.com
この書き方では、name、age、emailといったキーは取り出していません。
取り出しているのは値だけです。
キーと値を取り出す書き方
連想配列では、キーと値をセットで取り出す書き方がよく使われます。
foreach ($array as $key => $value) {
// 処理
}
たとえば、次のように書きます。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
foreach ($user as $key => $value) {
echo $key . " : " . $value . "<br>";
}
出力結果は次のとおりです。
name : 山田太郎
age : 25
email : taro@example.com
この場合、$keyにはキーが入り、$valueには値が入ります。
つまり、1回目のループでは次のようになります。
$key = "name"
$value = "山田太郎"
2回目のループでは、次のようになります。
$key = "age"
$value = 25
3回目のループでは、次のようになります。
$key = "email"
$value = "taro@example.com"
連想配列を扱う場合は、この$key => $valueの形をまず覚えるとよいです。
foreachで連想配列を処理する流れ
連想配列は1要素ずつ順番に処理される
次の配列を例にします。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
この配列をforeachで処理すると、配列の中身が1つずつ取り出されます。
foreach ($user as $key => $value) {
echo $key . ":" . $value . "<br>";
}
処理の流れは次のようになります。
1回目:name => 山田太郎
2回目:age => 25
3回目:email => taro@example.com
foreachは、配列の要素数だけ繰り返し処理を行います。
この例では要素が3つあるため、ループも3回実行されます。
foreachは現在の配列順で処理する
PHPの配列は、基本的に要素を追加した順番を保持します。
$data = [
"first" => "最初",
"second" => "2番目",
"third" => "3番目"
];
foreach ($data as $key => $value) {
echo $key . ":" . $value . "<br>";
}
出力結果は次のようになります。
first:最初
second:2番目
third:3番目
ただし、foreachが必ず「最初に書いた順番」で処理するというより、正確には「現在の配列の順番」で処理します。
たとえば、ksort()などで配列を並び替えた場合は、並び替え後の順番で処理されます。
$data = [
"b" => "B",
"a" => "A",
"c" => "C"
];
ksort($data);
foreach ($data as $key => $value) {
echo $key . ":" . $value . "<br>";
}
出力結果は次のようになります。
a:A
b:B
c:C
つまり、foreachは現在の配列の並び順に従って処理する、と理解すると正確です。
HTMLとforeachを組み合わせる
連想配列を一覧表示する
PHPでは、連想配列の内容をHTMLに表示する場面がよくあります。
たとえば、プロフィール情報をリストで表示する場合は、次のように書けます。
$profile = [
"名前" => "佐藤花子",
"職業" => "Webデザイナー",
"居住地" => "東京"
];
echo "<ul>";
foreach ($profile as $key => $value) {
echo "<li>" . $key . ":" . $value . "</li>";
}
echo "</ul>";
出力されるHTMLは次のようなイメージです。
<ul>
<li>名前:佐藤花子</li>
<li>職業:Webデザイナー</li>
<li>居住地:東京</li>
</ul>
このように、連想配列とforeachを使うと、キーを項目名として、値を内容として表示できます。
HTMLに表示する場合はhtmlspecialcharsを使う
HTMLに値を表示するときは、セキュリティ対策としてhtmlspecialchars()を使うのが基本です。
たとえば、次のように書きます。
$user = [
"名前" => "山田太郎",
"年齢" => 25,
"メールアドレス" => "taro@example.com"
];
foreach ($user as $key => $value) {
echo htmlspecialchars($key, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . ":";
echo htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . "<br>";
}
htmlspecialchars()を使う理由は、XSSと呼ばれる攻撃を防ぐためです。
たとえば、ユーザーが入力した値に次のような文字列が含まれていたとします。
<script>alert('危険')</script>
この文字列をそのままHTMLに出力すると、ブラウザ上でJavaScriptが実行されてしまう可能性があります。
そのため、画面に表示する値は基本的にエスケープします。
実務では、毎回htmlspecialchars()を書くと長くなるため、次のような関数を用意しておくことも多いです。
function h($value): string
{
return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
この関数を使うと、次のように書けます。
foreach ($user as $key => $value) {
echo h($key) . ":" . h($value) . "<br>";
}
コードが短くなり、読みやすくなります。
連想配列をテーブルで表示する
基本的なテーブル表示
連想配列をHTMLテーブルで表示することもできます。
$user = [
"名前" => "山田太郎",
"年齢" => 25,
"メールアドレス" => "taro@example.com"
];
echo "<table>";
echo "<tbody>";
foreach ($user as $key => $value) {
echo "<tr>";
echo "<th>" . h($key) . "</th>";
echo "<td>" . h($value) . "</td>";
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
このコードでは、キーをth、値をtdとして表示しています。
表示イメージは次のようになります。
名前 山田太郎
年齢 25
メールアドレス taro@example.com
学習用のコードでは<table border="1">のように書かれることもありますが、実務では見た目はCSSで指定する方が自然です。
echo '<table class="user-table">';
CSS側で次のように指定します。
.user-table {
border-collapse: collapse;
}
.user-table th,
.user-table td {
border: 1px solid #ccc;
padding: 8px;
}
PHPではデータを出力し、デザインはCSSで管理するのが基本です。
多次元配列をforeachで処理する
配列の中に連想配列が入っている形
実務では、連想配列が複数入った配列を扱うことがよくあります。
たとえば、複数ユーザーのデータは次のように表せます。
$users = [
[
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
],
[
"name" => "佐藤花子",
"age" => 30,
"email" => "hanako@example.com"
],
[
"name" => "鈴木一郎",
"age" => 28,
"email" => "ichiro@example.com"
]
];
この配列は、外側がインデックス配列で、内側が連想配列になっています。
つまり、次のようにアクセスできます。
echo $users[0]["name"];
この場合、出力されるのは次の値です。
山田太郎
外側と内側をforeachで処理する
複数ユーザーのデータをすべて表示する場合は、foreachを入れ子にして処理できます。
foreach ($users as $user) {
foreach ($user as $key => $value) {
echo h($key) . ":" . h($value) . "<br>";
}
echo "<hr>";
}
このコードでは、外側のforeachでユーザーを1人ずつ取り出します。
内側のforeachで、そのユーザーのname、age、emailを取り出します。
処理のイメージは次のとおりです。
1人目のユーザーを取り出す
nameを表示
ageを表示
emailを表示
2人目のユーザーを取り出す
nameを表示
ageを表示
emailを表示
3人目のユーザーを取り出す
nameを表示
ageを表示
emailを表示
多次元配列をテーブルで表示する
ユーザー一覧をテーブルにする
複数ユーザーのデータは、テーブルで表示すると見やすくなります。
<?php
function h($value): string
{
return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
$users = [
[
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
],
[
"name" => "佐藤花子",
"age" => 30,
"email" => "hanako@example.com"
],
[
"name" => "鈴木一郎",
"age" => 28,
"email" => "ichiro@example.com"
]
];
?>
<table class="user-table">
<thead>
<tr>
<th>名前</th>
<th>年齢</th>
<th>メールアドレス</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?= h($user["name"] ?? "") ?></td>
<td><?= h($user["age"] ?? "") ?></td>
<td><?= h($user["email"] ?? "") ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
このコードでは、foreachを使ってユーザー情報を1行ずつ表示しています。
また、$user["name"] ?? ""のように書くことで、もしnameキーが存在しない場合でもエラーを避けられます。
PHPの代替構文を使うとHTML内で読みやすい
上のコードでは、次のような書き方を使っています。
<?php foreach ($users as $user): ?>
HTML
<?php endforeach; ?>
これはPHPの代替構文です。
HTMLの中でforeachを書く場合は、波括弧を使うよりも読みやすくなることがあります。
通常の書き方は次のとおりです。
<?php
foreach ($users as $user) {
echo "<tr>";
echo "<td>" . h($user["name"] ?? "") . "</td>";
echo "</tr>";
}
?>
HTMLが多い場合は、代替構文を使った方が構造を把握しやすくなります。
foreachで条件分岐を使う
キーによって表示内容を変える
連想配列では、キーを使って処理を分けることもできます。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
foreach ($user as $key => $value) {
if ($key === "email") {
echo "メールアドレス:" . h($value) . "<br>";
} else {
echo h($key) . ":" . h($value) . "<br>";
}
}
この例では、キーがemailのときだけ表示ラベルを変えています。
連想配列では、キーに意味があるため、このようにキーを条件分岐に使えるのが便利です。
continueで特定の項目をスキップする
特定のキーだけ表示したくない場合は、continueを使えます。
$user = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
foreach ($user as $key => $value) {
if ($key === "email") {
continue;
}
echo h($key) . ":" . h($value) . "<br>";
}
このコードでは、キーがemailのときは表示せず、次のループに進みます。
continueは、その回の処理をスキップして、次の繰り返しに進むための命令です。
foreachで配列の値を変更する
通常のforeachでは元の配列は変わらない
foreachで取り出した$valueを変更しても、通常は元の配列は変わりません。
$prices = [
"apple" => 100,
"banana" => 150,
"orange" => 200
];
foreach ($prices as $key => $value) {
$value = $value * 1.1;
}
print_r($prices);
出力結果は次のようになります。
Array
(
[apple] => 100
[banana] => 150
[orange] => 200
)
$valueを変更しても、元の$pricesには反映されていません。
元の配列を変更する場合はキーを使って代入する
元の配列を変更したい場合は、キーを使って代入します。
$prices = [
"apple" => 100,
"banana" => 150,
"orange" => 200
];
foreach ($prices as $key => $value) {
$prices[$key] = $value * 1.1;
}
print_r($prices);
出力結果は次のようになります。
Array
(
[apple] => 110
[banana] => 165
[orange] => 220
)
このように、$prices[$key]に新しい値を代入すれば、元の配列を更新できます。
初心者のうちは、この書き方を使うのがおすすめです。
処理の意味が分かりやすく、参照による思わぬバグも避けやすいからです。
参照渡しで変更する方法
foreachでは、&を使って値を参照として取り出すこともできます。
$prices = [
"apple" => 100,
"banana" => 150,
"orange" => 200
];
foreach ($prices as $key => &$value) {
$value = $value * 1.1;
}
unset($value);
print_r($prices);
出力結果は次のようになります。
Array
(
[apple] => 110
[banana] => 165
[orange] => 220
)
この方法でも元の配列を変更できます。
ただし、参照渡しを使った場合は、foreachの後にunset($value)を書くのが安全です。
unset($value);
参照渡しのforeachでは、ループが終わったあとも$valueが最後の要素への参照を持ったままになることがあります。
その状態で別の処理を書くと、意図しないバグにつながる可能性があります。
そのため、初心者のうちは参照渡しよりも、次のようにキーを使って代入する書き方の方が安全です。
foreach ($prices as $key => $value) {
$prices[$key] = $value * 1.1;
}
foreachとforの違い
forは回数や数値インデックスで処理したいときに使う
forは、繰り返し回数を指定して処理したいときに便利です。
$fruits = ["apple", "banana", "orange"];
for ($i = 0; $i < count($fruits); $i++) {
echo $fruits[$i] . "<br>";
}
このコードでは、$iを使って配列の0番目、1番目、2番目を順番に表示しています。
ただし、連想配列ではこの方法は向いていません。
$user = [
"name" => "山田太郎",
"age" => 25
];
for ($i = 0; $i < count($user); $i++) {
echo $user[$i];
}
このコードは期待どおりに動きません。
なぜなら、$userには0や1というキーが存在しないからです。存在するキーはnameとageです。
連想配列ではforeachの方が自然
連想配列を処理する場合は、foreachを使う方が自然です。
$user = [
"name" => "山田太郎",
"age" => 25
];
foreach ($user as $key => $value) {
echo $key . ":" . $value . "<br>";
}
連想配列はキーが文字列であることが多いため、数値のカウンターで処理するより、foreachでキーと値を取り出す方が分かりやすくなります。
空の配列をforeachした場合
空の配列ではループの中身は実行されない
空の配列をforeachで処理しても、エラーにはなりません。
$items = [];
foreach ($items as $item) {
echo $item;
}
この場合、配列の中に要素がないため、ループの中身は一度も実行されません。
画面には何も表示されません。
データがない場合の表示を用意する
実務では、データが空だった場合の表示を用意することが多いです。
$items = [];
if (empty($items)) {
echo "データがありません。";
} else {
foreach ($items as $item) {
echo h($item) . "<br>";
}
}
このように書けば、配列にデータがないときに「データがありません。」と表示できます。
ただし、$itemsという変数自体が未定義の場合は注意が必要です。
未定義の変数をforeachで処理しようとすると警告が出る可能性があります。
安全に書くなら、次のように初期化しておくとよいです。
$items = $items ?? [];
foreach ($items as $item) {
echo h($item) . "<br>";
}
実務でよくある使用例
商品一覧を表示する
ECサイトや商品紹介ページでは、商品データを配列で持ち、foreachで一覧表示することがあります。
$products = [
[
"name" => "Tシャツ",
"price" => 2500,
"stock" => 12
],
[
"name" => "スニーカー",
"price" => 8900,
"stock" => 5
],
[
"name" => "バッグ",
"price" => 6500,
"stock" => 0
]
];
foreach ($products as $product) {
echo "<div class='product'>";
echo "<h3>" . h($product["name"] ?? "") . "</h3>";
echo "<p>価格:" . h($product["price"] ?? "") . "円</p>";
if (($product["stock"] ?? 0) > 0) {
echo "<p>在庫あり</p>";
} else {
echo "<p>在庫なし</p>";
}
echo "</div>";
}
このコードでは、商品ごとに名前、価格、在庫状況を表示しています。
foreachを使えば、商品数が3件でも100件でも、同じ処理で一覧表示できます。
お問い合わせフォームの確認画面に使う
お問い合わせフォームの確認画面でも、連想配列とforeachはよく使われます。
$formData = [
"お名前" => "山田太郎",
"メールアドレス" => "taro@example.com",
"お問い合わせ内容" => "サービスについて質問があります。"
];
foreach ($formData as $label => $value) {
echo "<dt>" . h($label) . "</dt>";
echo "<dd>" . nl2br(h($value)) . "</dd>";
}
nl2br()は、改行を<br>に変換する関数です。
お問い合わせ内容のように複数行のテキストを表示する場合に便利です。
ただし、実際のフォーム処理では、$_POSTの中身をそのまますべて表示するのは避けた方が安全です。
表示してよい項目をあらかじめ決めておくと安心です。
$labels = [
"name" => "お名前",
"email" => "メールアドレス",
"message" => "お問い合わせ内容"
];
foreach ($labels as $key => $label) {
$value = $_POST[$key] ?? "";
echo "<dt>" . h($label) . "</dt>";
echo "<dd>" . nl2br(h($value)) . "</dd>";
}
このように、表示する項目をホワイトリスト化しておくと、想定外のデータを画面に出してしまうリスクを減らせます。
foreachでよくあるミス
keyとvalueの順番を逆にしてしまう
foreachでキーと値を取り出すときは、次の順番で書きます。
foreach ($array as $key => $value) {
// 処理
}
間違えて次のように書くと、意味が逆になってしまいます。
foreach ($array as $value => $key) {
// 処理
}
PHPとしては動く場合がありますが、$valueという名前の変数にキーが入り、$keyという名前の変数に値が入るため、コードが非常に分かりにくくなります。
基本は次の形で覚えましょう。
foreach ($array as $key => $value) {
echo $key . ":" . $value;
}
連想配列をforで処理しようとする
連想配列をforで処理しようとすると、期待どおりに動かないことがあります。
$user = [
"name" => "山田太郎",
"age" => 25
];
for ($i = 0; $i < count($user); $i++) {
echo $user[$i];
}
この配列には0や1というキーがないため、$user[$i]では値を取得できません。
連想配列では、基本的にforeachを使いましょう。
foreach ($user as $key => $value) {
echo $key . ":" . $value . "<br>";
}
HTMLに値をそのまま出力してしまう
次のように、値をそのままHTMLへ出力するのは避けた方がよいです。
echo $value;
ユーザーが入力した値をそのまま表示すると、XSSの原因になる可能性があります。
HTMLに表示する場合は、基本的に次のようにエスケープします。
echo htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
または、エスケープ用の関数を作っておくと便利です。
function h($value): string
{
return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
echo h($value);
配列やオブジェクトをそのままechoしようとする
foreachで取り出した値が文字列や数値なら、echoで表示できます。
しかし、値が配列の場合は注意が必要です。
$user = [
"name" => "山田太郎",
"skills" => ["PHP", "JavaScript"]
];
foreach ($user as $value) {
echo $value . "<br>";
}
この場合、skillsの値は配列です。配列をそのままechoしようとすると、警告が出る可能性があります。
配列が入る可能性がある場合は、次のように処理を分けます。
foreach ($user as $key => $value) {
if (is_array($value)) {
echo h($key) . ":" . h(implode(", ", $value)) . "<br>";
} else {
echo h($key) . ":" . h($value) . "<br>";
}
}
値の型によって表示方法を変えることも、実務では重要です。
foreachで使う変数名の考え方
データの意味が分かる名前にする
foreachでは、変数名を分かりやすくするとコードが読みやすくなります。
たとえば、ユーザー一覧を処理するなら次のように書きます。
foreach ($users as $user) {
echo h($user["name"] ?? "");
}
商品一覧なら、次のように書けます。
foreach ($products as $product) {
echo h($product["name"] ?? "");
}
記事一覧なら、次のように書けます。
foreach ($posts as $post) {
echo h($post["title"] ?? "");
}
このように、配列全体は複数形、1件分のデータは単数形にすると、意味が分かりやすくなります。
キーと値を扱う場合の変数名
キーと値を扱う場合は、一般的に次のように書きます。
foreach ($user as $key => $value) {
echo h($key) . ":" . h($value);
}
ただし、表示項目のラベルと内容を扱う場合は、次のような名前も分かりやすいです。
foreach ($profile as $label => $text) {
echo h($label) . ":" . h($text);
}
変数名に正解はありませんが、「何が入っているか」が分かる名前にすることが大切です。
まず覚えるべきforeachの実用パターン
キーと値を表示するパターン
連想配列の基本は、キーと値を取り出す形です。
$data = [
"name" => "山田太郎",
"age" => 25,
"email" => "taro@example.com"
];
foreach ($data as $key => $value) {
echo h($key) . ":" . h($value) . "<br>";
}
まずはこの形を覚えるとよいです。
foreach ($array as $key => $value) {
// 処理
}
一覧データを表示するパターン
複数のデータを一覧表示する場合は、外側の配列から1件ずつ取り出します。
$users = [
[
"name" => "山田太郎",
"email" => "taro@example.com"
],
[
"name" => "佐藤花子",
"email" => "hanako@example.com"
]
];
foreach ($users as $user) {
echo h($user["name"] ?? "") . " / " . h($user["email"] ?? "") . "<br>";
}
データベースから取得した一覧データも、このような形で処理することが多いです。
HTMLに安全に表示するパターン
HTMLに表示する場合は、エスケープを忘れないようにします。
foreach ($users as $user) {
echo "<p>";
echo h($user["name"] ?? "");
echo " / ";
echo h($user["email"] ?? "");
echo "</p>";
}
ユーザー入力やデータベースの値を画面に出すときは、基本的にhtmlspecialchars()でエスケープすると覚えておくとよいです。
まとめ
PHPのforeachは、連想配列を扱ううえで非常に重要な構文です。
連想配列では、キーと値をセットで管理します。
$user = [
"name" => "山田太郎",
"age" => 25
];
このような配列を処理するときは、次の形を使います。
foreach ($user as $key => $value) {
echo $key . ":" . $value;
}
値だけを取り出す場合は、次のように書きます。
foreach ($user as $value) {
echo $value;
}
元の配列を変更したい場合は、キーを使って代入します。
foreach ($prices as $key => $value) {
$prices[$key] = $value * 1.1;
}
HTMLに表示する場合は、セキュリティ対策としてhtmlspecialchars()を使います。
echo htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
実務では、次のようなエスケープ用の関数を用意しておくと便利です。
function h($value): string
{
return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
foreachは、ユーザー情報、商品一覧、記事一覧、フォーム確認画面、データベースの取得結果など、さまざまな場面で使われます。
まずは、次の基本形をしっかり覚えておきましょう。
foreach ($array as $key => $value) {
// キーと値を使った処理
}
連想配列を扱うPHPコードでは、foreachを自然に使えるようになることが大切です。
以上、PHPのForeachと連想配列についてでした。
最後までお読みいただき、ありがとうございました。










