【PHP入門2021】ループ繰り返し処理③ foreach文で配列のループ

PHP

ループ繰り返し処理のforeach文

PHPのforeachは配列や連想配列を順番に参照して、繰り返しループ処理を行う構文です。

forやwhileでも実現できますが、foreachを使った方が記述がシンプルになります。

ループ繰り返し処理 foreach文の基本構文

通常の配列のforeach文の基本構文

foreach(配列 as 配列の値を代入する変数){
	取り出した配列の処理
}

連想配列のforeach文の基本構文

foreach(配列 as 配列のキーを代入する変数 => 配列の値を代入する変数){
	取り出した配列の処理
}

※as のあとの =>の左がキー、右が値。キーは省略できます

ループ繰り返し処理 foreach文のサンプルソースコード

通常の配列でループするサンプルソースコード

まずは通常の配列の内容をすべて出力してみます。

$list = array(
	"1番目", //インデックス0
	"2番目", //インデックス1
	"3番目", //インデックス2
);

foreach($list as $element){ //配列のインデックスを順番にループ
	echo $element . PHP_EOL;
}
出力結果
1番目
2番目
3番目

連想配列でループするサンプルソースコード

foreach文では連想配列も扱えます。

$map = array(
	"1番目" => "猿",
	"2番目" => "犬",
	"3番目" => "キジ",
);

foreach($map as $key => $name){ //配列のインデックスを順番にループ
	echo "{$key}の仲間は「{$name}」です" . PHP_EOL;
}
出力結果
1番目の仲間は「猿」です
2番目の仲間は「犬」です
3番目の仲間は「キジ」です

foreach文での配列のindexとkeyの関係

配列やforeachの理解を深めるには非常に重要な説明をします。

サンプルを通常配列と連想配列の2例紹介しました。
実はこれらは内部ではまったく同じ処理です。キーを省略したかどうかだけの違いです。

データ型の章で配列と連想配列の違いを紹介しているので詳細はそちらを読んでみてください。

配列と連想配列の違いの真実

PHPの配列は通常こんな説明されることが多いです。

「通常の配列はインデックスで管理され、連想配列はキーと値のセットで管理されている」

しかし、本当に配列を理解するには以下のことを理解してください。

PHPの配列は全て連想配列が基本です。実は例外は通常の配列の方。
0からはじまる連番の正の値である「インデックス」をキーとするというルールを持つ連想配列のことを通常の配列と呼んでいます。

キーにルールがあるためキー名を省略することが可能となっているだけなのです。

foreach文の構文も配列と連想配列は同じだった・・

以下の通常の配列と連想配列はまったく同じ内容のものです。

#通常の配列
$list = array(
	"1番目", //インデックス0
	"2番目", //インデックス1
	"3番目", //インデックス2
);

#連想配列
$map = array(
	0 => "1番目", //インデックス0
	1 => "2番目", //インデックス1
	2 => "3番目", //インデックス2
);

実は前述の紹介した通常配列のforeachの構文は連想配列のキーが省略されただけのものだったのです

■通常の配列

foreach(配列 as 配列の値を代入する変数){
	取り出した配列の処理
}

■連想配列
foreach(配列 as 配列のキーを代入する変数 => 配列の値を代入する変数){
	取り出した配列の処理
}

↓この理解が正しいです。

「as のあとの =>の左がキー、右が値。キーは省略できる」

わざとキーの省略を入れ替えた例

インデックスの省略をしない

//通常配列だがforeach文でキー(インデックス)を省略しない
$list = array(
	"1番目", //インデックス0
	"2番目", //インデックス1
	"3番目", //インデックス2
);

foreach($list as $index => $element){ //配列のインデックスを順番にループ
	echo "{$index}: {$element}" . PHP_EOL;
}

キーの省略をする

//連想配列だがforeach文でキーを省略する
$map = array(
	"1番目" => "猿",
	"2番目" => "犬",
	"3番目" => "キジ",
);

foreach($map as $element){ //配列のインデックスを順番にループ
	echo $element . PHP_EOL;
}

foreach文で多次元配列をループする

多次元配列は配列の中にさらに配列を含む形の配列です。
多くの場合はis_array()などを用いてループの中で配列かどうか確認するような条件分岐を挟むことになるでしょう。

$heroes = array(

	"タマオ" => array(
		"職業" => "勇者",
		"レベル" => 32,
		"持ち物" => array(
			"伝説の剣",
			"やくそう",
		),
	),
	"タマコ" => array(
		"職業" => "魔法使い",
		"レベル" => 99,
		"持ち物" => array(
			"光の玉",
		),
		"魔法" => array(
			"ファイヤー",
			"バリア",
		),
	),

);

//一人ずつのデータを順番にループ
foreach($heroes as $name => $hero){
	echo "■「{$name}」 ==================" . PHP_EOL;
	//一人分の項目を全てループ
	foreach($hero as $col => $value){
		if(is_array($value)){ //$valueが配列なら
			echo "$col: " . PHP_EOL;
			foreach($value as $value2){ //さらに配列の中身を出力
				echo "\t{$value2}" . PHP_EOL;  //値を出力
			}
		}else{ //$valueが配列以外なら
			echo "{$col}: {$value}" . PHP_EOL; //値を出力
		}
	}
}
■「タマオ」 ==================
職業: 勇者
レベル: 32
持ち物: 
	伝説の剣
	やくそう
■「タマコ」 ==================
職業: 魔法使い
レベル: 99
持ち物: 
	光の玉
魔法: 
	ファイヤー
	バリア

foreach文の配列のループで参照渡し

値の代入では値の更新ができない

今まで紹介したforeachの記述方法では渡した配列の内容自体を書き換えることはできません。それはforeachで宣言した変数は代入と同様で値のコピーとなるからです。

$list = array(
	"1番目", //インデックス0
	"2番目", //インデックス1
	"3番目", //インデックス2
);

foreach($list as $element){ //配列のインデックスを順番にループ
	$element = null; //配列の値をnullにしたいが・・・
}

print_r($list);
出力結果
Array
(
    [0] => 1番目
    [1] => 2番目
    [2] => 3番目
)

消したかったのに値を更新できませんでした。

参照渡しなら値の更新はできる

&をつけると配列の値が参照渡しになり値を更新することができます

$list = array(
	"1番目", //インデックス0
	"2番目", //インデックス1
	"3番目", //インデックス2
);

foreach($list as &$element){ //配列のインデックスを順番にループ
	$element = null; //配列の値をnullにする
}

print_r($list);
出力結果
Array
(
    [0] => 
    [1] => 
    [2] => 
)

今度は値を更新できました。

※参照渡しが可能なのは値のみで、キーに参照渡しは使えません

参照については以下のページで詳しく説明しているので参考にしてください。

foreach文のスキップ(continue)

ある条件を満たすときだけ処理をスキップしたい、というときはcontinueを使います。

continueのサンプルソースコード

$map = array(
	"1番目" => "猿",
	"2番目" => "犬",
	"3番目" => "キジ",
);

$idx = 0;
foreach($map as $key => $name){ //配列のインデックスを順番にループ
	if($idx >= 1){
		echo "スキップします" . PHP_EOL;
		continue;
	}
	echo "{$key}の仲間は「{$name}」です" . PHP_EOL;
	++$idx;
}
1番目の仲間は「猿」です
スキップします
スキップします

continueは直近の条件分岐やループ処理をスキップします。具体的にはswitch/for/foreach/whileです。

foreach文の強制終了・脱出(break)

while自体のループ実行条件とは別に、ある条件を満たすとループ処理を中断して終了させたいといったときはbreakを使います。

breakのサンプルソースコード

$map = array(
	"1番目" => "猿",
	"2番目" => "犬",
	"3番目" => "キジ",
);

$idx = 0;
foreach($map as $key => $name){ //配列のインデックスを順番にループ
	if($idx >= 1){
		echo "中断します" . PHP_EOL;
		break;
	}
	echo "{$key}の仲間は「{$name}」です" . PHP_EOL;
	++$idx;
}
1番目の仲間は「猿」です
中断します

breakは直近の条件分岐やループ処理を中断します。具体的にはswitch/for/foreach/whileです。

コメント

タイトルとURLをコピーしました