状態:-
閲覧数:5,296
投稿日:2010-04-25
更新日:2014-10-09
1.値のみ
配列の要素のみを抽出
foreach( 配列 as $val ){
ループ処理;
}
指定した配列に関してループ処理を実行。実行時には現在の要素の値が変数$valに代入され、配列ポインタが1つ進められる。なお、foreach文の実行開始時には配列ポインタが自動的に配列の先頭要素に戻る。また、配列が リファレンス でない限り、foreachは、指定した配列自体に対してではなく、 そのコピーに対して処理を実施する。そのため、このやり方のforeach文で要素の値を変数に格納しても、値のコピーが変数に代入されるだけで、要素の値を利用することはできても、要素の値自体を変更することはできない。ループ処理;
}
2.キーと値
キー(インデックス、添え字)と値を一緒に抽出
foreach( 配列 as $key => $val ){
ループ処理;
}
各ループでの現在の要素の値が変数$valに、要素のキーが変数$keyに代入される。ループ処理;
}
その他
配列の要素のみを抽出(「&演算子」を利用してリファレンスを受け取る)
foreach( 配列 as & $val )
ループ処理;
unset($val);
■PATTERN1(配列の要素(値)のみを抽出/最も簡単なforeach文)
$week = array( "月", "火", "水", "木", "金", "土", "日");
foreach($week as $value)
{
print $value;
print "
";
}
▼結果
http://php.w4c.work/originalSample/diagram/Section19/foreach1.php
■PATTERN1(配列の要素(値)のみを抽出/「抽出された配列」と「元の配列」には関係がないことを確認する例)
$arr = array("値1", "キー1" => "値2", "値3");
foreach($arr as $tmp){//$arrの値を 次々に変数 $tmp に代入
$tmp = "{$tmp}の値利用";//変数$tmp の値を書換 (配列$arrの値を書き換えたわけではない)
echo $tmp."
";//書換後の$tmp が表示される。( 配列$arrとは何の関係もない)
}
foreach($arr as $tmp){//配列$arrには何の変更もしていないので、$arrの初期値のまま表示
echo $tmp."
";
}
▼結果
/demo/foreach01.html
■PATTERN2(要素とそのインデックス(添え字)も一緒に抽出)
$member = array( "氏名" => "山田太郎",
"年齢" => 20,
"身長" => 170);
foreach($member as $key => $value )
{
print "$key : $value";
print "
";
}
▼結果
http://php.w4c.work/originalSample/diagram/Section19/foreach2.php
■PATTERN2
$arr = array("値1", "キー1" => "値2", "値3");
foreach($arr as $key => $tmp){ //$arrのキーと値を 次々に変数 $keyと$tmp に代入
$arr[$key] = "{$tmp}更新"; //$arr[$key]で配列$arrの値を書き換えた
echo $tmp."
";//$tmpの値は変更していないので最初の値のまま表示される。
echo $arr[$key]."
";//配列$arrの値を全部「{値}更新」に書き換えているので、「{値}更新」で表示される
}
foreach($arr as $key => $tmp){
echo $tmp."
";//上で配列$arrの値を全部「{値}更新」に書き換えているので、「{値}更新」で表示される
}
▼結果
/demo/foreach02.html
■PATTERN1、■PATTERN2
$arr = array("NARITA", "HANEDA", "KOBE");//「変数$arr」に3つの要素を持った配列を格納
//配列の要素のみを抽出
foreach($arr as $val){//配列の要素の数だけループ実行される。最初のループで「配列$arr」内の先頭の要素を「変数$val」に格納し、処理内でその変数を使う。2回目のループで「配列$arr」内の2番目の要素を「変数$val」に格納し、処理内でその変数を使う...ということを、配列の最後の要素に到達するまで継続
echo $val;
echo "
";
}
echo "
";
//要素とそのインデックス(添え字)も一緒に抽出
foreach($arr as $key => $val){//「変数$key」に配列のインデックスを、「変数$val」に要素を格納していく
echo $key;
echo " : ";
echo $val;
echo "
";
}
▼結果
/demo/foreach.html
■PATTERN1、■PATTERN2 - 「オブジェクト」の「プロパティ(メンバ変数)」を走査する例
class AIRPORT{
var $var1 = "NARITA";
var $var2 = "HANEDA";
var $var3 = "KOBE";
}
$obj = new AIRPORT;
//オブジェクトが保持するプロパティ(メンバ変数)の数だけループし、各プロパティの値が抽出
foreach($obj as $val){//「変数$obj」に「AIRPORT」クラスのオブジェクトを格納
echo $val;
echo "
";
}
echo "
";
foreach($obj as $name => $val){//「変数$name」にプロパティ名を、「変数$val」にプロパティの値を格納していく
echo $name;
echo " : ";
echo $val;
echo "
";
}
▼結果
/demo/foreach_object.html
■PATTERN1、■PATTERN2 - 「オブジェクト」の「プロパティ(メンバ変数)」を走査する例 - PHP5
アクセス可能なプロパティのみ出力される。また、クラスメンバであるスタティックプロパティは(オブジェクトプロパティではないので)出力されない。
class C1{
public $p1 = "publicプロパティ。フツーは設定すべきではない(型が自由だからどんな型でも入ってしまうのは問題。チェックとかを挟む意味でもprivateにするべき)";
protected $p2 = "protectedなプロパティ";
private $p3 = "privateなプロパティ";
static public $p4 = "staticなプロパティ";
public function __construct(){//②
$i = 0;
echo "****** C1::__construct() 開始 ******\n";
foreach($this as $name => $val){
$i++;
echo $name, " : ", $val, "\n";
}
echo "****** C1::__construct() 終了 ******\n";
echo '$i : ', $i, "\n\n";//ループ回数はアクセス可能なプロパティ数 = 効率的に、アクセス可能なプロパティの数だけループされる
}
}
class C2 extends C1{
public function __construct(){//④
$i = 0;
echo "****** C2::__construct() 開始 ******\n";
foreach($this as $name => $val){
$i++;
echo $name, " : ", $val, "\n";
}
echo "****** C2::__construct() 終了 ******\n";
echo '$i : ', $i, "\n\n";
}
}
new C1;//①
$obj = new C2;//③
$i = 0;//⑤
echo "****** class外 開始 ******\n";
foreach($obj as $name => $val){
$i++;
echo $name, " : ", $val, "\n";
}
echo "****** class外 終了 ******\n";
echo '$i : ', $i;
▼結果
/demo/foreach4_objectproperty.html
■PATTERN2、■PATTERN3 - 直接配列の値を変更
$arr = array("値1", "キー1" => "値2", "値3");
foreach($arr as $key => $val){
$arr[$key] = "{$val}更新";#ループ中に値を更新
}
foreach($arr as $key => $val){
echo str_pad($key, 5), " : ", $val, "\n";//str_pad ? 文字列を固定長の他の文字列で埋める
}
echo "\n";
foreach($arr as &$val){ #ループ中に値を更新(リファレンスを受け取る)
$val = "{$val}再更新";
}
unset($val);//foreach文が終了しても変数「val」には配列の最後の要素に対する参照「$arr[2]」が設定されたままのため、「$val」をアンセット。unset() は指定した変数を破棄
foreach($arr as $key => $val){
echo str_pad($key, 5), " : ", $val, "\n";
}
/*
※ループ前に「$val」をアンセットしていないと下記の様な結果になる
「$arr[2]」に「$arr[0]」がセットされる→「0 : 値1更新再更新」を出力
「$arr[2]」に「$arr[1]」がセットされる→「キー1 : 値2更新再更新」を出力
「$arr[2]」に「$arr[2]」がセットされる→「1 : 値2更新再更新」を出力←ここの「$arr[2]」とは、実質的に直前にセットされた「$arr[1]」
*/
#変数ではないものからリファレンスを受け取ろうとすると、Parse error: syntax error, unexpected '&', expecting T_STRING or T_VARIABLE or '$'
/*
foreach(array("air", "PORT") as &$val){
//
}
*/
▼結果
/demo/foreach3_ref.html
PHPのforeach文は、キー順が維持される
全てキー順を維持
・PHP Sandboxで色々なバージョンを試したが、全てキー順を維持
$data = array(1=>'1',5=>'5',2=>'2');
foreach ($data as $key => $value) {
echo $key." ";
}
1 5 2
PHP仕様
配列も連想配列
・連想配列には並び順の概念がある