foreach文

制御構造

 状態:-  閲覧数:5,151  投稿日: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文は、キー順が維持される

 閲覧数:619 投稿日:2014-10-09 更新日:2014-10-09 

全てキー順を維持


・PHP Sandboxで色々なバージョンを試したが、全てキー順を維持
$data = array(1=>'1',5=>'5',2=>'2');

foreach ($data as $key => $value) {
echo $key." ";
}

1 5 2


PHP仕様


配列も連想配列
・連想配列には並び順の概念がある


for文

break文

コメント投稿(ログインが必要)



類似度ページランキング
順位 ページタイトル抜粋
1 foreach文 100
2 for文 67
3 break文 57
4 preg_match 56
5 Doctrine 50
6 realpath 50
7 Generators 44
8 Propel 43
9 session.hash_function 41
10 switch文 40
11 syntax error 40
12 include_path 40
13 set_error_handler 40
14 array_filter 40
15 array_reduce 40
16 phpinfo 40
17 SessionHandler::gc 38
18 ob_start 38
19 register_shutdown_function 35
20 Composer 35
2024/6/14 2:17 更新
週間人気ページランキング / 6-7 → 6-13
順位 ページタイトル抜粋 アクセス数
1 PHPで定数を定義する方法は2種類ある / 配列定数の定義 9
2 コード例 … 「例外処理」はネストすることができる 5
2 ブラウザを閉じたらセッションデータはどうなるの? | セッション 5
3 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 4
4 ガベージコレクション | 機能 3
4 Warning: Unexpected character in input: '\' (ASCII=92) state=1 in ○○.php on line △△ | Warning(エラーメッセージ) 3
4 curl で Cookie を使用する 3
4 PHPにおけるメソッドのオーバーライドについて /「引数の数や型は、親クラスのメソッドと完全に一致していなければなりません。」とは具体的にどういう意味ですか? 3
4 Catchable fatal error: Object of class DateTime could not be converted to string | Fatal error(エラーメッセージ) 3
4 Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] Connection refused | Fatal error(エラーメッセージ) 3
4 Warning: include() [function.include]: Failed opening '**.php' for inclusion (in | Warning(エラーメッセージ) 3
4 ( ! ) Deprecated: implode(): Passing glue string after array is deprecated. Swap the parameters in ★★★ headless-chromium-php/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php | エラーメッセージ 3
5 Fatal error: Wrong parameters for Exception([string $exception [, long $code ]]) | Fatal error(エラーメッセージ) 2
5 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 2
5 Fatal error: require_once(): Failed opening required 'PEAR.php' | Fatal error(エラーメッセージ) 2
5 Fatal error: Uncaught RuntimeException: SplFileObject::__construct(): failed to open stream: Permission denied in | Fatal error(エラーメッセージ) 2
5 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'カラム名' cannot be null | Fatal error(エラーメッセージ) 2
5 session_start() | セッション 2
5 @ | 演算子 2
5 Parse error: syntax error, unexpected T_REQUIRE_ONCE, expecting T_FUNCTION | Parse error(エラーメッセージ) 2
2024/6/14 1:01 更新