downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | conferences | my php.net

search for in the

break> <for
[edit] Last updated: Sat, 07 Jan 2012

view this page in

foreach

PHP 4는 펄이나 다른 언어처럼 foreach구문을 지원합니다. 이런 구문은 간단하게 배열에 대한 작업을 수행하는 가장 쉬운 기법입니다. foreach는 배열에서만 작동하고 다른 데이터형을 갖는 변수나 초기화되지 않은 변수에 대해서 이 구문을 사용하려한다면 에러 메시지를 만날것입니다. 이 구문은 두가지 문법이 있습니다; 두번째보다는 첫번째문법이 더 유용한 사용법입니다:

foreach (array_expression as $value)
    statement
foreach (array_expression as $key => $value)
    statement

첫번째 형태는 array_expression에서 주어진 배열에 대해 루프를 돈다. 각 루프에서 현재 배열 원소의 값은 $value 로 지정되고 내부적인 배열 포인터는 하나씩 이동하게 된다 (그래서 다음 루프에서 다음 배열 원소를 보게 될것이다)

두번째 루프도 같은 일을 한다. 단 현재 배열 원소의 키(key)값은 각 루프의 $key변수로 지정된다.

PHP 5부터 객체 순환도 할 수 있습니다.

Note:

foreach문이 처음 실행할때, 내부적인 배열 포인터는 자동적으로 배열의 첫번째 원소로 리셋된다. 따라서 foreach절 이전에 reset()함수를 호출할 필요는 없다.

Note:

배열이 참조되지 않는 이상, foreach는 지정한 배열 자체가 아닌 복사한 배열을 대상으로 작동합니다. foreach는 배열 포인터에 영향이 있습니다. foreach 도중이나 이후에는 리셋하지 않은 배열 포인터에 의존하지 마십시오.

PHP 5부터, $value 앞에 &를 붙여서 배열 원소를 쉽게 변경할 있습니다. 값을 복사하지 않고 참조합니다.

<?php
$arr 
= array(1234);
foreach (
$arr as &$value) {
    
$value $value 2;
}
// $arr은 이제 array(2, 4, 6, 8)입니다.
unset($value); // 마지막 원소로 참조를 제거합니다.
이는 반복할 배열을 참조할 수 있을 때(즉, 변수)만 가능합니다.

Warning

$value 참조와 마지막 배열 원소는 foreach 루프 뒤에도 남아 있습니다. unset()으로 제거하는 것을 권합니다.

Note:

foreach는 '@'를 사용해서 에러메시지를 출력하지 못하도록 할 수 없습니다.

다음 예는 기능적으로 동일하다는것을 알 필요가 있다:

<?php
$arr 
= array("하나""둘""셋");
reset($arr);
while (list(, 
$value) = each($arr)) {
    echo 
"값: $value<br />\n";
}

foreach (
$arr as $value) {
    echo 
"값: $value<br />\n";
}
?>
다음 예도 기능적으로 동일하다:
<?php
$arr 
= array("하나""둘""셋");
reset($arr);
while (list(
$key$value) = each($arr)) {
    echo 
"키: $key; 값: $value<br />\n";
}

foreach (
$arr as $key => $value) {
    echo 
"키: $key; 값: $value<br />\n";
}
?>

더 많은 예제 코드들이 사용법에 대해서 설명해준다:

<?php
/* foreach 예제 1: 값만 */

$a = array(12317);

foreach (
$a as $v) {
   echo 
"\$a의 현재 값: $v.\n";
}

/* foreach 예제 2: 값 (표시를 위해 수동으로 접근 순서를 출력) */

$a = array(12317);

$i 0/* 가상 목적으로만 사용 */

foreach ($a as $v) {
    echo 
"\$a[$i] => $v.\n";
    
$i++;
}

/* foreach 예제 3: 키와 값 */

$a = array(
    
"one" => 1,
    
"two" => 2,
    
"three" => 3,
    
"seventeen" => 17
);

foreach (
$a as $k => $v) {
    echo 
"\$a[$k] => $v.\n";
}

/* foreach 예제 4: 다차원 배열 */

$a = array();
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";

foreach (
$a as $v1) {
    foreach (
$v1 as $v2) {
        echo 
"$v2\n";
    }
}

/* foreach 예제 5: 동적 배열 */

foreach (array(12345) as $v) {
    echo 
"$v\n";
}
?>



break> <for
[edit] Last updated: Sat, 07 Jan 2012
 
add a note add a note User Contributed Notes foreach - [12 notes]
up
20
tedivm at tedivm dot com
4 years ago
foreach and the while/list/each methods are not completely identical, and there are occasions where one way is beneficial over the other.

<?php
$arr
= array(1,2,3,4,5,6,7,8,9);

foreach(
$arr as $key=>$value)
{
    unset(
$arr[$key + 1]);
    echo
$value . PHP_EOL;
}
?>
Output:
1 2 3 4 5 6 7 8 9

<?php
$arr
= array(1,2,3,4,5,6,7,8,9);

while (list(
$key, $value) = each($arr))
{
    unset(
$arr[$key + 1]);
    echo
$value . PHP_EOL;
}
?>
Output:
1 3 5 7 9


[EDIT BY danbrown AT php DOT net: Contains a typofix by (scissor AT phplabs DOT pl) on 30-JAN-2009.]
up
19
dtowell
10 months ago
References created by foreach hang around past their best-used-by date. For example, the following:

<?php
$a
= array('abe','ben','cam');
foreach (
$a as $k=>&$n)
   
$n = strtoupper($n);
foreach (
$a as $k=>$n) // notice NO reference here!
   
echo "$n\n";
print_r($a);
?>

will result in:

ABE
BEN
BEN
Array
(
    [0] => ABE
    [1] => BEN
    [2] => BEN
)
up
14
adam dot sindelar at gmail dot com
5 years ago
You can also use the alternative syntax for the foreach cycle:

<?php
foreach($array as $element):
 
#do something
endforeach;
?>

Just thought it worth mentioning.
up
8
billardmchl at aol dot com
2 years ago
This function find well the words, add well adds a () around short words, but the
array at the end of th function is the same as at the beginning.

<?php
function isole_mots($chaine)
{
   
$chaine = "le petit chat est fou";
   
$mots = preg_split('/[!,-.;?:()[ ]/', $chaine, -1, PREG_SPLIT_NO_EMPTY);
    foreach (
$mots as $mot)
    {
        if (
strlen($mot) <= 3)
           
$mot = "(".$mot.")";
    print
" inside foreach $mot <br>";
    }
print
"after foreach array mots";   
   
print_r($mots);
    die();
    return
$mots;
}
?>

inside foreach (le)
inside foreach petit
inside foreach chat
inside foreach (est)
inside foreach (fou)
after foreach array motsArray ( [0] => le [1] => petit [2] => chat [3] => est [4] => fou )
up
6
Oleg englishman at bigmir dot net
2 years ago
For those who'd like to traverse an array including just added elements (within this very foreach), here's a workaround:

<?php
$values
= array(1 => 'a', 2 => 'b', 3 => 'c');
while (list(
$key, $value) = each($values)) {
    echo
"$key => $value \r\n";
    if (
$key == 3) {
       
$values[4] = 'd';
    }
    if (
$key == 4) {
       
$values[5] = 'e';
    }
}
?>

the code above will output:

1 => a
2 => b
3 => c
4 => d
5 => e
up
4
php at darkain dot com
3 months ago
"Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset()."

I cannot stress this point of the documentation enough! Here is a simple example of exactly why this must be done:

<?php
$arr1
= array("a" => 1, "b" => 2, "c" => 3);
$arr2 = array("x" => 4, "y" => 5, "z" => 6);

foreach (
$arr1 as $key => &$val) {}
foreach (
$arr2 as $key => $val) {}

var_dump($arr1);
var_dump($arr2);
?>

The output is:
array(3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> &int(6) }
array(3) { ["x"]=> int(4) ["y"]=> int(5) ["z"]=> int(6) }

Notice how the last index in $arr1 is now the value from the last index in $arr2!
up
9
nobody at nobody dot com
1 year ago
<?php
$d3
= array('a'=>array('b'=>'c'));
foreach(
$d3['a'] as &$v4){}
foreach(
$d3 as $v4){}
var_dump($d3);
?>
will get something look like this:
array(1) {
  ["a"]=>
  array(1) {
    ["b"]=>
    &array(1) {
      ["b"]=>
      *RECURSION*
    }
  }
}
then you try to walk some data with this array.
the script run out of memory and connect reset by peer

the document says:
Warning
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

so what I learn is that NEVER ignore """Warning""" in document....
up
3
php at electricsurfer dot com
10 years ago
[Ed Note:  You can also use array_keys() so that you don't have to have the $value_copy variable --alindeman at php.net]

I use the following to modify the original values of the array:

<?php
foreach ($array as $key=>$value_copy)
{
    
$value =& $array[$key];
    
// ...
    
$value = 'New Value';
}
?>
up
1
Voitcus at wp dot pl
1 year ago
You can even iterate through "dynamic" arrays that do not physically exist, but are objects that implement Iterator interface. They don't need to be stored in memory when foreach starts.

Consider the array that contains some values (I called it $allValues in the example below) and we want to have only some of them (eg. the ones that are dividable by 2). I create an object that would serve as dynamic array, that means it would "dynamically update" its values together with $allValues. The main advantage is that I store only one array, and it's the only array I serialize.

An object of MyIter class will not contain any values itself:
<?php
class MyIter implements Iterator { // you can implement ArrayAccess and Countable interfaces too, this will make class MyIter behave like a "real" array
 
private $position = 0; // an internal position of the current element
  // please note that $position has nothing common with $allValues!

 
private function getTable(){ // prepare a temporary "static" table of all objects in the class
   
global $allValues;
   
$result=array(); // temporary variable
   
foreach($allValues as $obj){
      if(
$obj % 2 == 0) // check if the value is even
       
$result[]=$obj; // if yes, I want it
     
}
    return
$result;
  }   

 
// the all below declared methods are public and belong to the Iterator interface
 
function rewind() { // a method to start iterating
   
$this->position = 0; // just move to the beginning
 
}

  function
current() { // retrieves the current element
   
$table=$this->getTable(); // let us prepare a table
   
return $table[$this->position]; // and return the current element
 
}

  function
key() { // retrieves the current element's key
   
return $this->position; // this is used by foreach(... as $key=>$value), not important here
 
}

  function
next() { // move to next element
   
++$this->position;
  }

  function
valid() { // check if the current element is valid (ie. if it exists)
   
return array_key_exists($this->position, $this->getTable());
  }
}
// end of class

// now prepare the array of 12 elements
$allValues=array(0,1,2,3,4,5,6,7,8,9,10,11);

//we would like to have a dynamic array of all even values
$iterator=new MyIter();

foreach(
$iterator as $value){
  echo
$value."<br />";
}
?>
This will result in:
0
2
4
6
8
10

(You may also like to see what var_dump($iterator) produces).

Another great advantage is that you can modify the main table "on-the-fly" and it has its impact. Let us modify the last foreach loop:
<?php
// ...all above shall stay as it was
foreach($iterator as $value){
  echo
$value."<br />";
  if(
$value==6){
   
$allValues=array(2,3);
    echo
"I modified source array!<br />";
  }
}
?>
This produces now:
0
2
4
6
I modified source array!

However, if you feel it is rather a catastrophic disadvantage (maybe for example, it shows the values 0, 4, and 6 which were removed when we reached 6), and wish to have a "static" array that will iterate even in modified objects, just call getTable() in rewind() method and save it in temporary (private perhaps) field. In my example getTable() is called every iteration, and it calls another foreach through $allValues, which together might be time-consuming. Consider what you need.
up
0
Ashus
2 months ago
If you wondered how to create a list of all possible combinations of variable amount of arrays (multiple foreach), you might use this:

<?php

$a
[0] = array('a1','a2');
$a[1] = array('b1','b2','b3');
$a[2] = array('c1','c2');

function
getAllCombinations($a,$i,$s)
    {
    foreach (
$a[$i] as $v)
        {
        if (!isset(
$a[$i+1]))
            {
            echo
$s.$v."\n";
            } else {
           
getAllCombinations($a,$i+1,$s.$v);
            }
        }
    return
$s;
    }

echo
getAllCombinations($a,0,'');

?>

the result:

a1b1c1
a1b1c2
a1b2c1
a1b2c2
a1b3c1
a1b3c2
a2b1c1
a2b1c2
a2b2c1
a2b2c2
a2b3c1
a2b3c2
up
-3
Luke at chaoticlogic dot net
5 years ago
Alright, I had a little error. I had one foreach() declaration, and then another foreach() declaration.

They went:
<?php
//$connections is an array of Socket resources
foreach ($connections as $key => &$value) {
   
//the code here is impertinent

}

//$users is an associative array
foreach ($users as $key => &$value) {
   
//the code here is impertinent
}
?>

Alright, now, what error was produced as a result of this?
This one:
"Warning: Cannot use scalar value as array in filename.php on line 69."

I then realized something; the reason for this came from the fact that I used $key, and $value for both of them in the exact same way.

As a response to this, I've developed two ways to fix this:
<?php
//add this to the end of every foreach() you use
unset($key,$value)
?>

OR

Simply use different variables for each one.
up
-9
simplex
6 years ago
"As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value."

There are cases where array_walk or array_map are inadequate (conditional required) or you're just too lazy to write a function and pass values to it for use with array_map...

My solution to foreach for php 4 and 5 to modify values of an array directly:

<?php

$testarr
= array("a" => 1, "b" => 2, "c" => 3, "d" => 4);

$testarr_keys = array_keys($testarr);
$testarr_values = array_values($testarr);

for (
$i = 0; $i <= count($testarr) - 1; $i++) {
   
$testarr[$testarr_keys[$i]] = $testarr_values[$i] * 2;
}

print_r($testarr);
?>

 
show source | credits | stats | sitemap | contact | advertising | mirror sites