PHP foreach: キーと値のペアで配列をループ

PHP の foreach は、手動でインデックスを追跡せずに配列や Traversable を実装したオブジェクトを反復処理するための、最も一般的な書き方です。各反復でキーと値の両方が必要な場合は foreach ($array as $key => $value) を使います。要素をその場で更新する場合は参照渡し(&$value)で反復し、意図しない上書きを防ぐために最後にループ変数を unset() してください。

キーと値を反復する PHP foreach の例

出力:

ここに出力が表示されます...

出力:

りんご: $1.2
パン: $2.5
牛乳: $0.99

この例の仕組み

  1. $prices は商品名を価格に対応付ける連想配列です。
  2. foreach ($prices as $item => $price) は、各反復で現在のキーを $item に、現在の値を $price に代入します。手動インデックスや count() は不要です。
  3. 各反復でキーと値のペアを出力します。foreach は添字配列と連想配列のどちらも同じ構文で処理できます。

PHP foreach でよくある間違い

参照渡しループ後の unset() を忘れる

悪い例:

foreach ($items as &$item) {
    $item = strtoupper($item);
}
foreach ($items as $item) {} // 最後の要素を上書きする

正しい例:

foreach ($items as &$item) {
    $item = strtoupper($item);
}
unset($item);

参照渡しの foreach の後は、ループ変数が最後の要素を指したままです。その変数を再利用すると、ローカルなループ値ではなく最後の要素が変更される可能性があります。

値渡しループで配列が更新されると思い込む

悪い例:

foreach ($prices as $price) {
    $price *= 1.10; // 配列ではなくコピーを変更
}

正しい例:

foreach ($prices as &$price) {
    $price *= 1.10;
}
unset($price);

値渡しの反復では、各 $price は要素のコピーです。そのコピーを変更しても元の配列には反映されません。

PHP foreach と for ループの違い

foreachfor
インデックス変数が不要で、全件走査では読みやすい。インデックス計算、ステップ増分、逆順走査が必要な場合に向いている。
連想配列と Traversable オブジェクトに対応。数値インデックスのみを前提とし、連想キーには array_keys() が必要。
間引き走査(例: 1つおき)にはやや不向き。$i += 2 や逆順カウントを自然に書ける。

標準的な配列の全件処理には foreach を使います。ループ本体が数値位置や非連続アクセスに依存する場合は for に切り替えてください。

FAQ

PHP の foreach ループでキーと値の両方を取得するには?

$key => $value 構文を使います: foreach ($array as $key => $value)。これにより、添字配列と連想配列のどちらでも、各反復でキー($key)と値($value)が代入されます。値だけが必要なら foreach ($array as $value) を使います。

foreach は配列だけでなくオブジェクトも反復できますか?

foreachTraversable インターフェースを実装する値であれば反復できます。これには IteratorIteratorAggregate の実装が含まれます。通常のオブジェクトではスコープに応じて可視プロパティを反復し、クラス内部では全プロパティ、クラス外部では public プロパティのみが対象です。

PHP の foreach と array_map の違いは何ですか?

foreach は制御構文で、各要素に対してブロックを実行し、echo のような副作用や早期 break を扱えます。array_map はコールバックを適用して新しい配列を返します。新しい配列が必要で、元データを変更したくない場合は array_map を使います。