30
[edit] Last updated: Fri, 24 Jun 2011 foreach  PHP 4 introdujo un constructor foreach, muy parecido al de Perl y algunos otros lenguajes. Simplemente da un modo fácil de iterar sobre arrays. foreach sólo trabaja sólo sobre arrays y resultará en un error al intentar usarlo en una variable con un diferente tipo de datos o una variable no inicializada. Hay dos sintaxis; la segunda es una extensión menor, pero útil de la primera: foreach (array_expression as $value) sentencias foreach (array_expression as $key => $value) sentencias La primera forma recorre el array dado por array_expression. En cada ciclo, el valor de el elemento actua es asignado a $value y el puntero interno del array es avanzado en uno (así en el próximo ciclo se estará mirando el siguiente elemento). La segunda manera hace lo mismo, excepto que la clave del elemento actual será asignada a la variable $key en cada ciclo. A partir de PHP 5, es posible iterar objetos también. Note: Cuando foreach inicia la primera ejecución, el puntero interno del array se pone automáticamente en el primer elemento del array. Esto significa que no es necesario llamar la función reset() antes de un bucle foreach. Note: A menos que el array este referenciado, foreach opera sobre una copia del array especificado y no sobre el propio array. foreach tiene algunos efectos secundarios sobre el puntero del array. No se puede confiar en el puntero del array durante o después del foreach sin reposicionarlo. A partir de PHP 5, se pueden modificar fácilmente elementos del array al preceder $value con &. Esto asignará una referencia en lugar de copiar el valor. <?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) {  $value = $value * 2; } // $arr ahora es array(2, 4, 6, 8) unset($value); // rompe la referencia con el último elemento ?> Esto sólo es posible si el array iterado puede ser referenciado (es decir, es una variable), lo que significa que el código siguiente no funciona: <?php foreach (array(1, 2, 3, 4) as &$value) {  $value = $value * 2; } ?> PHP: f oreach - Manual http://www.php.net/manual/es/control-struct ures.foreach.php 1 de 30 29-07-2011 12:31

PHP_ Foreach - Manual

Embed Size (px)

Citation preview

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 1/30

[edit] Last updated: Fri, 24 Jun 2011

fo reach  

PHP 4 introdujo un constructor foreach, muy parecido al de Perl y algunos otros lenguajes. Simplementeda un modo fácil de iterar sobre arrays. foreach sólo trabaja sólo sobre arrays y resultará en un error alintentar usarlo en una variable con un diferente tipo de datos o una variable no inicializada. Hay dossintaxis; la segunda es una extensión menor, pero útil de la primera:

foreach (array_expression as $value)sentencias

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

La primera forma recorre el array dado por array_expression. En cada ciclo, el valor de el elemento actuaes asignado a $value y el puntero interno del array es avanzado en uno (así en el próximo ciclo se estarámirando el siguiente elemento).

La segunda manera hace lo mismo, excepto que la clave del elemento actual será asignada a la variable$key en cada ciclo.

A partir de PHP 5, es posible iterar objetos también.

Note:

Cuando foreach inicia la primera ejecución, el puntero interno del array se pone automáticamente enel primer elemento del array. Esto significa que no es necesario llamar la función reset() antes de unbucle foreach.

Note:

A menos que el array este referenciado, foreach opera sobre una copia del array especificado y nosobre el propio array. foreach tiene algunos efectos secundarios sobre el puntero del array. No sepuede confiar en el puntero del array durante o después del foreach sin reposicionarlo.

A partir de PHP 5, se pueden modificar fácilmente elementos del array al preceder $value con &. Estoasignará una referencia en lugar de copiar el valor.

<?php

$arr = array(1, 2, 3, 4);

foreach ($arr as &$value) {  $value = $value * 2;

}

// $arr ahora es array(2, 4, 6, 8)

unset($value); // rompe la referencia con el último elemento

?>

Esto sólo es posible si el array iterado puede ser referenciado (es decir, es una variable), lo que significaque el código siguiente no funciona:

<?php

foreach (array(1, 2, 3, 4) as &$value) {

  $value = $value * 2;

}

?>

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 2/30

Warning

Referencia del $value y el último elemento del array permanecen aún después delbucle foreach. Se recomienda destruirlos con unset().

Note:

foreach no soporta la capacidad de suprimir mensajes de error usando '@'.

Puede haber notado que las siguientes son funcionalmente idénticas:

<?php

$arr = array("uno", "dos", "tres");

reset($arr);

while (list(, $value) = each($arr)) {

echo "Valor: $value<br />\n";

}

foreach ($arr as $value) {

echo "Valor: $value<br />\n";

}

?>

Las siguientes también son funcionalmente idénticas:

<?php

$arr = array("uno", "dos", "tres");reset($arr);

while (list($key, $value) = each($arr)) {

echo "Clave: $key; Valor: $value<br />\n";

}

foreach ($arr as $key => $value) {

echo "Clave: $key; Valor: $value<br />\n";

}

?>

Algunos ejemplos más para demostrar su uso:

<?php

/* foreach ejemplo 1: sólo valor */

$a = array(1, 2, 3, 17);

foreach ($a as $v) {

echo "Valor actual de \$a: $v.\n";

}

/* foreach ejemplo 2: valor (con su notación de acceso manual impreso con fines ilustrativos)

$a = array(1, 2, 3, 17);

$i = 0; /* sólo para efectos ilustrativos */

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 3/30

foreach ($a as $v) {

echo "\$a[$i] => $v.\n";

  $i++;

}

/* foreach ejemplo 3: clave y valor */

$a = array(  "uno" => 1,

  "dos" => 2,

  "tres" => 3,

  "diecisiete" => 17

);

foreach ($a as $k => $v) {

echo "\$a[$k] => $v.\n";

}

/* foreach ejemplo 4: arrays multi‐dimensionales */

$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 ejemplo 5: arrays dinámicos */

foreach (array(1, 2, 3, 4, 5) as $v) {

echo "$v\n";

}

?>

 User Contributed Notes foreach

cuonghuyto  03-Jun-2011 10:14Note that foreach does zero loop on an empty array

<?php

foreach (array() as $value){

echo $value; // Prints nothing here

}

?>

(This is in an effort to make a strict specification of PHP functions/constructs)

gcocatre at gmail dot com 22-May-2011 12:29

The following code produces an unexpected result:

<?php

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 4/30

$a = array ('zero', 'one', 'two', 'three');

foreach ($a as $key => $value)

echo "$key: $value\n";

var_dump(key($a));

/* Produces:

0: zero

1: one

2: two3: three

int(1)

*/

?>

Reset your array after using foreach on it!

billardmchl at aol dot com 20-May-2011 08:20

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 )

broshizzledizzle at gmail dot com 17-Mar-2011 09:04

@benekastah

You are unintentionality misleading people.

Your code is the same as this:

<?php

$array = array('a', 'b', 'c', 'd');

foreach ( $array as $letter )

;echo $letter;

?>

What I mean by this is that you execute the foreach loop but don't do anything with it. The

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 5/30

reason you can echo the last value in the array is because of the warning posted above:

"Reference of a $value and the last array element remain even after the foreach loop. It is

recommended to destroy it by unset()."

someone 16-Mar-2011 09:07

It seems when you use references in a foreach, and then you add elements to the array within

it, it only runs through them if the current element isn't the last of the array (with 5.2.11

at least).

benekastah at gmail dot com 14-Mar-2011 05:26

It's good to know that if you accidentally (or purposefully) put a semicolon at the end of the

first line of a foreach statement, no error or warning will be thrown. Instead, the foreach

will iterate only on the last entry in the array. Therefore,

<?php

$array = array('a', 'b', 'c', 'd');

foreach ( $array as $letter ); // <‐‐Semicolon at end of foreach statement

  echo $letter;

?>

will only echo 'd' as it's response (rather than 'abcd'). I don't know if this is meant to be

the case, or if it is meant to err.

Mark Rose 15-Dec-2010 10:55

Be careful recycling the $value variable if using a reference! I recently ran into a strange

bug, where the last item of a second foreach loop was referenced.

<?php

$foo = array('one', 'two', 'three');

foreach ($foo as &$bar)

{ // no‐op

}

var_dump($foo);

foreach ($foo as $bar)

{

 // no‐op

}

var_dump($foo);

?>

produces:

array(3) {

[0]=>string(3) "one"

[1]=>string(3) "two"

[2]=>&string(5) "three"

}

array(3) {

[0]=>string(3) "one"

[1]=>string(3) "two"

[2]=>&string(3) "two"

}

Note that the last value in the array gets set to the second last value!

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 6/30

Alex S. 09-Dec-2010 03:18

Just found a way without a counter handling last element in a foreach :

<?php

$foo = ($current_key == count($array)‐1) ? "last element" : "any other element";

?>

fabiolimasouto at gmail dot com 02-Dec-2010 03:39

I've been using this foreach structure for two years or so now, and just figured something new

which i hadn't realized before, please have a look at this:

<?php

class Test

{

private $data;

function &data()

{

return $this‐>data;

}

 

function getData()

{

return $this‐>data;

}

}

$obj = new Test;

$data =& $obj‐>data();

$array = array('a','b','c');

foreach($array as $data){

}

echo $obj‐>getData(); // OUTPUTS: "c"!!!

?>

What I can say from this is that if you pass a reference to the data holder of the foreach

structure instead of a non‐declared or normal (non‐reference) variable, you will be able to

fill that same (referenced) space in memory without creating a new one. Note that this is

slightly different as explained in the manual above:

<?php

$arr = array(1, 2, 3, 4);

foreach ($arr as &$value) {

  $value = $value * 2;

}

// $arr is now array(2, 4, 6, 8)

unset($value); // break the reference with the last element

?>

In this case $value will simply point to the original addresses of each $array's elements in

each iteration. In my example the $data variable is before anything already pointing to

another address elsewhere and will have THAT memory location filled in each iteration!!! HopeI've made this somewhat understandable.

Sipos Tams 13-Nov-2010 06:37

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 7/30

This is an example of the use of the second, minor case of foreach.

A useful script that returns the relative URL of the current page with the current "GET data".

<?php

function getCurrentURL() {

  $currentURL = basename($_SERVER["PHP_SELF"]);

  $i = 0;

foreach($_GET as $key => $value) {  $i++;

if($i == 1) { $currentURL .= "?"; }

else { $currentURL .= "&amp;"; }

  $currentURL .= $key."=".$value;

}

return $currentURL;

}

?>

Note that most of the time basename($_SERVER["REQUEST_URI"] is enough for this task as well,

but if in the browsers's address bar is only http://example.com/ instead of http://example.com

/index.php displayed, than basename($_SERVER["REQUEST_URI"] fails.

Oleg englishman at bigmir dot net 14-Sep-2010 02:12

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

 j dot vd dot merwe at enovision do t net 26-Aug-2010 12:11

A sample how to go through a list of array elements that resulted from mysql recordset. In

this sample it checks if a file exists and removes the row from the array if it not.

<?php

$db‐>set_query("select * from documents where document_in_user = 0"); //1

$documents = $db‐>result_to_array($db‐>get_result()); //1

foreach ($documents as $key => $row) { //2

  $file = "uploads/".rawurldecode($row['document_name']);

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 8/30

 

if ( file_exists ( $file ) == FALSE ) {

unset($documents[$key]); //3

  }

}

$documents = array_values($documents); // reindex the array (4)

?>

variables:

mysql table = documents,

array = $documents

array key (index) = $key

array row (record sort of speak) = $row

explanation:

1.

it gets the array from the table (mysql)

2.foreach goes through the array $documents

3.

unset if record does not exist (remove the row)

4.

the array_values($documents) reindexes the $documents array, for otherwise you might end up in

trouble when your process will start expecting an array starting with key ($key) 0 (zero).

himitsu at fnse dot de 08-Aug-2010 12:59

Your last value changes after use of references.

<?php

$arr = array(' one ', ' two ', ' tree ', ' four ', ' five ');

print_r($arr);

foreach ($arr as &$str)

  $str = trim($str);

print_r($arr);

foreach ($arr as $str)

echo $str . "\n";

print_r($arr);

?>

Array ( Array ( one Array (

[0] => one [0] => one two [0] => one

[1] => two [1] => two tree [1] => two

[2] => tree [2] => tree four [2] => tree

[3] => four [3] => four four [3] => four

[4] => five [4] => five [4] => four

) ) )

<?php

$arr = array(' one ', ' two ', ' tree ', ' four ', ' five ');

foreach ($arr as &$str)

  $str = trim($str);foreach ($arr as $str) {

  print_r($arr);

echo $str . "\n";

}

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 9/30

print_r($arr);

?>

[0] => one => one => one => one => one => one

[1] => two => two => two => two => two => two

[2] => tree => tree => tree => tree => tree => tree

[3] => four => four => four => four => four => four

[4] => one => two => tree => four => four => four

tested in PHP 5.2.4 and PHP 5.3.0

cornvalley at gmail dot com 28-Jul-2010 11:39

Foreach can be also used to move around multiple tables.

Here is simple example.

<?php

$table[0][0][0] = 6;

$table[0][0][1] = 17;

$table[0][0][2] = 12;

$table[0][0][3] = 8;

$table[0][1][0] = 9;

$table[0][1][1] = 13;

$table[0][1][2] = 11;

$table[0][1][3] = 5;

$table[0][2][0] = 1;

$table[1][1][0] = 4;

$table[1][2][0] = 2;

$table[2][4][1] = 1;

foreach ($table as $i1 => $n1)

foreach ($n1 as $i2 => $n2)

foreach ($n2 as $i3 => $n3)  printf('$table[%d][%d][%d] = %d;<br>', $i1,$i2,$i3,$n3);?>

It gives the result:

$test[0][0][0] = 6;

$test[0][0][1] = 17;

$test[0][0][2] = 12;

$test[0][0][3] = 8;

$test[0][1][0] = 9;

$test[0][1][1] = 13;

$test[0][1][2] = 11;

$test[0][1][3] = 5;

$test[0][2][0] = 1;$test[1][1][0] = 4;

$test[1][2][0] = 2;

$test[2][4][1] = 1;

Kris dot Craig at gmail dot com 09-Jun-2010 06:42

If you're looking for a quick and easy way to recursively pull data from an MD array, here's a

little function that should come in handy:

<?php

  /* Grab any values from a multidimensional array using infinite recursion. ‐‐Kris */

  function RecurseArray( $inarray, $toarray ){

foreach ( $inarray as $inkey => $inval )

{

if ( is_array( $inval ) )

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 10/30

{

  $toarray = $this‐>RecurseArray( $inval, $toarray );

}

else

{

  $toarray[] = $inval;

}

}

  return $toarray;

}

?>

John 17-May-2010 11:38

For those wishing to try the heresy of adding to an array while it is being processed in a

foreach loop, note that your added value will not be processed at the end of the loop!

<?php

$arr = array(1,2,3,4,5);

foreach($arr as $val) if($val==3) $arr[]=6; else echo $val;

?>

will show "1245" not "12456".

 jsimlo at yahoo dot com 19-Dec-2009 12:31

There is currently no syntax to write a single yet lazy‐evaluated foreach thru multiple

arrays, but you can double‐foreach like this (this is not lazy‐evaluated yet):

<?php

foreach (array ($array1, $array2, $array3) as $control)

foreach ($control as $item)

echo $item;

?>

The above will echo all items from all three input arrays. Note that simple array_merge might

not always work (sicne array_merge might depend on the type of array keys) and might consume

more memory in the process. The reasonable grounds for doing this might be a more complicated

body of the foreach, which you do not want to repeat in your code for every input array, or a

fact that you got too many input arrays.

Now, a lazy‐evaluation trick would look something like this (although php is capable of

optimizations that fully neglect reasons for doing things like this):

<?php

foreach (array ('array1', 'array2', 'array3') as $control)

foreach ($$control as $item)

echo $item;

?>

And finally, a lazy‐evaluation trick that might be reasonable:

<?php

foreach (array ('expr1', 'expr2', 'expr3') as $control)

foreach (eval ($control) as $item)

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 11/30

if ($item) break 2; else echo $item;

?>

Example (searching for a non‐trivial value):

<?php

// search for a child name$seachName = 'Jozko';

// prepare the sources

$sources = array (

  '$item1‐>GetChilds()',

  '$item2‐>GetChilds()',

  '$item3‐>GetParent()‐>GetChilds()',

  '$item3‐>GetComputeSomethingDifficultChilds()',

);

// search in several different arrays

foreach ($sources as $control)foreach (eval ($control) as $child)

if ($child‐>GetName() == $seachName) break 2;

// now we got the correct child

// and we did it in lazy‐evaluation style

print_r ($child);

mazdak dot farrokhzad at piratpartiet dot se 24-Sep-2009 04:49

This is a really silly example of how you can implement foreach for objects in a really crazy

way...

It's not something you should use...

<?php

  /**

* Same as foreach, for objects...

*

* @param object|array $_collection

* @param callback $_lambda

* @param mixed $_data optional

* @return void

*/

  function loop($_collection, $_lambda, $_data = null){

if(is_array($_collection))

{

foreach($_collection as $key => $value)

{

if(is_null($_data))

  $_lambda($key, $value);

else

  $_lambda($key, $value, $_data);

}

}

elseif(is_object($_collection)){

  $iter = $_collection‐>getIterator();

  $iter‐>rewind();

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

e 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 12/30

while($iter‐>valid())

{

if(is_null($_data))

  $_lambda($iter‐>key(), $iter‐>current());

else

  $_lambda($iter‐>key(), $iter‐>current(), $_data);

  $iter‐>next();

}}

else

  trigger_error('Only Accepts Objects or Arrays', E_USER_ERROR);

}

  // and this is how to use it...

  $data = "some random data"; // you can place $this here

  loop(new ArrayObject(array(1,2,3,4)), function(&$_key, &$_value, &$_data)

{

echo $_key.$_value.$_data;

}, $data);

?>

s dot mattison at gmail dot filtersoutmyspam dot com 10-Sep-2009 10:19

I hope other people find this useful.

<?php

/*

‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐

"Null" Array filler

by Steve Mattison

This script shows one way PHP candisplay an array, and pad it with

'nonexistant' values. This may be

useful, for instance, in reducing

the size of a database by storing

only values that deviate from a

set standard.

‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐

*/

$arr = array(3, 5, ‐47); //the values. we're looking for the first two.

//an arbitrary lower number must append the array.

//this is so the main loop continues after the last value has been found.

$arr2 = array("oranges", "pears", null); //value descriptions.

foreach ($arr as $key=>$value) { //get next value that we seek.

  for($iterate=$last+1;$iterate<10;$iterate++){ //iterate a loop.

//start at the last position+1, in case we've already looped once.

//if we haven't looped yet, $last is not defined; we start at 1.

  $last=$iterate; //keep track of our position.

  echo '<br>['.$iterate.'] ‐ '; //show it.

  if($iterate==$value){ //an array value has appeared.

  echo ($arr2[$key]); //show the deviant value.

  break; //break the loop and get the next value.

  } //end if

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 13/30

  else echo ("apples"); //otherwise show the default value.

  } //next $iterate

//array values higher than the loop condition will be ignored.

//optionally, you may wish to check for this and display them here.

} //next‐each $arr

unset($value); //clear up the memory used by foreach

//Example Result Set:

//[1] ‐ apples

//[2] ‐ apples

//[3] ‐ oranges

//[4] ‐ apples

//[5] ‐ pears

//[6] ‐ apples

//[7] ‐ apples

//[8] ‐ apples

//[9]‐apples

?>

Krzysztof - ksobolewski at o2 dot pl 09-Jul-2009 11:50

The weird behaviour of references in foreach remains as long as in PHP 5.2.08 (Linux) and PHP

5.2.9 (Windows XP). The simplest example would be:

<?php

$a = array('a', 'b','c');

foreach($a as &$row){

  //you don't have to do anything here

  }  print_r($a);

foreach($a as $row){

echo "<br />".$row;

}

?>

the result of print_r will be correct ‐ array of ('a','b','c') values. The second foreach,

however, would

produce a,b,b. For all arrays, regardless of size, it would be the n‐1 element

(the element right before the last one). Eg. for 'a','b','c','d','e','f', the script would

produce a,b,c,d,e,e.

There are few solutions to this:

1. safest ‐ avoid using references in foreach; so instead of

<?php

foreach($a as &$row){

  // do something, eg.

  $row = trim($row);

}

?>

you would use

<?phpforeach($a as $i=>$row){

  // do something on row, eg.

  $row = trim($row);

  // replace the row in the table

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 14/30

  $a[$i]=$row;

}

?>

decrease of performance is the cost, however

2. equally safe and more usable ‐ unset the element reference right after the foreach loop

with references, eg.:

<?php

$a = array('a', 'b','c');foreach($a as &$row){

  //you don't have to do anything here

  }

unset ($row)); // it is safe now to use $row again

  print_r($a);

foreach($a as $row){

echo "<br />".$row;

}

?>

3. use references in both case; it seems that iterations work correct if you use &$row in both

loops or don't use it in any:

<?php

$a = array('a', 'b','c');

foreach($a as &$row){

  //you don't have to do anything here

  }

  print_r($a);

  // works OK now even without unset($row)

  foreach($a as &$row){

echo "<br />".$row;

}

?>

4. use references in foreach only inside functions or methods; outside the function scope it

should be safe

<?php

function cleanTable($a){

foreach($a as &$row){

  $row = trim($row);

}

}

$a = array('a','b','c');cleanTable($a);

foreach($a as $row){

echo "<br />".$row;

}

?>

drawbacks: NONE! I Quite contrary, the code looks more tidy.

5. avoid using the same variable names for referenced and non‐referenced values; for example,

in the first case use &$rRow, and in the second one ‐ $row. It's neither elegant, nor

efficient, though, as each new variable lowers the application performance a bit.

<?php$a = array('a', 'b','c');

foreach($a as &$rRow){ // $rRow for 'referenced row'

//you don't have to do anything here

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 15/30

  }

  print_r($a);

foreach($a as $row){

echo "<br />".$row;

}

?>

burleigh at chorus dot net 04-May-2009 05:21Using numeric indexes doesn't automatically sort your array.

<?php

$titles[3] = 'three';

$titles[2] = 'two';

$titles[1] = 'one';

print_r( $titles);

 

foreach ($titles as $t ) {

print "title=$t ";

}

?>

will display:

Array ( [3] => three [2] => two [1] => one )

title=three title=two title=one

If you want the items coming out in the correct order you need to use sort

<?php

sort($titles);print_r($titles);

?>

Array ( [0] => one [1] => three [2] => two )

grobemo 24-Apr-2009 06:13

You may want to do something different on the last iteration through a foreach loop. For

instance, if you're printing a series of HTML list elements, you may want to add a class like

'last' to the final <li> element.

I had trouble finding a good way to do this with a foreach loop. The following code

illustrates the method I worked out.

<?php

$array = array('apples','bananas','cranberries','durians');

$last_item = end($array);

foreach($array as $item) {

if ($item == $last_item) {

print "I like to eat " . $item;

}

}

?>

The foreach loop outputs: 'I like to eat durians'.

Technically, you could just use if ($item == end($array)), but I assume that would require

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 16/30

more processing time.

strata_ranger at hotmail dot com 19-Apr-2009 05:03

Note that foreach() iterates through an array in the same order that its elements were

defined. If you want to iterate through an array in a different order, you will need to sort

the array prior to entering the loop.

For example:

<?php

// Iterate through an array in reverse order,

// maintaining key association (i.e. for associative arrays)

foreach(array_reverse($array, true) as $key=>$value)

{

. . .

}

?>

timgolding_10 at hotmail dot com 09-Apr-2009 09:50

Here's an example where one can loop through two or more arrays in one loop. this example hastwo arrays.

<?php

$array1=array("a", "b", "c");

$array2=array("1", "2", "3");

foreach(array_merge($array1, $array2) as $value)

{

echo $value;

}

// abc123

?>

For more arrays just add them as additional arguments to the array_merge function. This

example isn't very useful if your loop needs to return the keys for numeric indexed arrays.

For associative arrays you can return the key however must be certain that all the indexes are

unique across all arrays.

tedivm at tedivm dot com 29-Jan-2009 10:44

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))

{

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 17/30

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.]

zodiac2800 at msn dot com 06-Nov-2008 05:36

Here is a way to declare global variable variables using a function.

This particular example handles an array that contains names of $_POST items. This is to avoid

the notices that php gives when checking an unused $_POST.

<?php

function check ($inputs) {

foreach ($inputs as $input) {

global $$input;

$$input = isset($_POST[$input]) ? $_POST[$input] : "";

}

}

?>

Robin Leffmann 26-Sep-2008 01:51

It should be noted that when using foreach to pass an array's key ($key => $value), the key

must be a string and not binary content ‐ containing 0's, f.e., as was my case when i used

foreach to parse bencoded data handed back to me from a bittorrent tracker scraping ‐ as this

will throw foreach off and hand you a key that is binary different than the actual content of

the array.

rhi 17-Sep-2008 10:22

If you use foreach with references, don't forget to unset the reference if you are not sure

that a later piece of code doesn't use the same variable name. Example:

<?php

$latest_tutorials = $db‐>queryAll("select * from tutorials"...);

foreach ($latest_tutorials as &$tut)

  $tut["comments"] = $db‐>queryOne("select count(*) ...");

// ...

$tut = $db‐>queryRow("...");

print_tutorials($latest_tutorials);

print_tutorial($tut);

?>

Here the last entry of latest_tutorials will be replaced by the row that is fetched by the

$tut = $db‐>queryRow("..."); line because $tut is still referencing the last array entry.

Solution:

<?php

foreach ($latest_tutorials as &$tut)

  $tut["comments"] = $db‐>queryOne("select count(*) ...");

unset($tut);

// ...

$tut = $db‐>queryRow("...");

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 18/30

?>

brian at diamondsea dot com 15-Aug-2008 03:15

A common problem is having PHP generate an error when trying to iterate through an array that

may sometimes have no data in it. This causes PHP to generate a warning such as:

Warning: Invalid argument supplied for foreach() in test.php on line 14

You can prevent this error by type‐casting the foreach variable as an array type using

"(array)" before the array variable name.

<?php

// double any value whose key starts with 'b'

$arr = array('a'=>1, 'b1'=>2, 'b2'=>3, 'c'=>4, 'd'=>5);

$non_array = null;

// Normal usage with an array

print "Test 1:\n";

foreach ($arr as $key => $val) {

print "Key $key, Value $val\n";

}

// Normal usage with a non‐array (undefined or otherwise empty data set)

// Outputs: Warning: Invalid argument supplied for foreach() in test.php on line 16

print "Test 2:\n";

foreach ($non_array as $key => $val) {

print "Key $key, Value $val\n";

}

// By casting the $non_array to an (array) type, it will function without error, skipping the

loopprint "Test 3:\n";

foreach ((array) $non_array as $key => $val) {

print "Key $key, Value $val\n";

}

print "Done.\n";

?>

Outputs:

Test 1:Key a, Value 1

Key b1, Value 2

Key b2, Value 3

Key c, Value 4

Key d, Value 5

Test 2:

Warning: Invalid argument supplied for foreach() in /home/bgallagher/test.php on line 16

Test 3:

Done.

adam dot sindelar at gmail dot com  14-Apr-2008 01:45

You can also use the alternative syntax for the foreach cycle:

<?php

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 19/30

foreach($array as $element):

  #do something

endforeach;

?>

Just thought it worth mentioning.

marian at devourmedia dot com 29-Feb-2008 01:34

Also, do not forget that foreach is not usefulif you change the value inside of the loop.

For example:

<?php

$t=array('a', 'a', 'a', 'a', 'a', 'a', 'a', '1', 'a', 'a', 'a', 'a', 'a');

foreach($t as $var=>$val)

{

$t=array();

echo "val={$val}<br>";

}

?>

is still showing the contents of the array $t.

henrik at newdawn dot dk 27-Oct-2007 10:08

As stated further up the foreach is consuming a lot of memory if used within large arrays ‐

that is ‐ if the array consists of for instance large objects. I had a case where a foreach

caused me to run out of the 256 MB memory that PHP is allowed to handle ‐ but changing to a

for() statement completly removed both memory and CPU load.

tcrosby at gmail dot com 27-Aug-2007 01:37

Using the much‐maligned ability of foreach to work on references rather than copies, it

becomes possible to recurse indefinitely into deep arrays without the need to know beforehand

how deep they go. Consider the following example (which I use to sanitize input):

<?php

// Sanitize as a function to allow recursing; original array passed by reference

function sanitize(&$array) {

foreach ($array as &$data) {

if (!is_array($data)) { // If it's not an array, clean it

  $data = '\\' . $data; // addslashes(), mysql_real_escape_string() or

whatever you wish to use, this is merely a simple example  }

else { // If it IS an array, call the function on it

  sanitize($data);

}

}

}

// Test case

$test = array(

array(

array(

  0,

  1,

  2

  ),

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 20/30

  3,

  4

  ),

  5,

  6

  );

// Output

sanitize($test);print_r($test);

/*

Output:

Array

(

[0] => Array

(

[0] => Array

([0] => \0

[1] => \1

[2] => \2

)

[1] => \3

[2] => \4

)

[1] => \5

[2] => \6

)

*/

?>

When first called on $test, it passes a reference to the original $test array to the sanitize

function, which begins to iterate through its contents with the immediate foreach loop. Each

value that is not in itself an array gets sanitized as normal, and as both the foreach loop

and the function itself are acting by reference, all changes happen directly to the contents

of the superglobal rather than to copies. If the value given IS an array, it then calls the

same function on it. The key here is that both the function and the foreach loop work by

reference, meaning that you can call the calling function while in the foreach loop and allchanges are still applied to the original array, without corruption of the array pointer, as

it remains intact for each level of the array. When the end of an array is reached, the

function simply returns; if it was a deeper‐level array, the parent function (and parent

foreach loop) continue as they were; if the top‐level loop ends, then the function returns to

the main code, having acted on the entire array. As everything operates within the scope of

the sanitize function, you even avoid the danger of leaving the last reference set, as $data

is not available outside the scope of the function in which any particular loop operates.

While this might sound complicated at first, the result is that by passing to foreach by

reference, true indefinite recursion is possible.

Luke at chaoticlogic dot net 02-Jul-2007 08:08

Alright, I had a little error. I had one foreach() declaration, and then another foreach()

declaration.

They went:

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 21/30

<?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.

27-Jan-2007 06:50

Here is an obvious question to most of the readers, but it took me about two precious minutesto figure out, so I figured I will share it will you:

What will be the output of the following statement:

<?php

$data = array('1' => 'field1', '2' => 'field2');

foreach ($data as $field_index => $field_name);

{

echo "$field_name";

}

?>

Correct answer is 'field2', and not 'field1field2'. The forgotten semicolon at the foreach

line does not trigger a syntax error, but php treats it as an empty statement..

and then the block is run once with the last value set into $field_name.

Timon Van Overveldt 15-Jan-2007 04:41

Why not just do this?

<?php

$arr = array(1, 2, 3, 4);

foreach ($arr as $i => $value) {

  $arr[$i] = $value * 2;

}// $arr is now array(2, 4, 6, 8)

?>

No need for references, so it works in both PHP4 and PHP5.

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 22/30

simplex 19-Dec-2006 08:12

"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);

?>

robycar at libero dot com 07-Dec-2006 07:04

some useful functions for testing boolean values

<?php

$trueValues = array('1', 'true', 't', 'y', 'yes', 'vero', 'v'); //edit with locale values

$falseValues = array('0', 'false', 'f', 'n', 'no', 'falso'); //edit with locale values

function str_to_bool($str) {foreach ($GLOBALS['trueValues'] as $value)

if (strcasecmp($str, $value) == 0)

return true;

foreach ($GLOBALS['falseValues'] as $value)

if (strcasecmp($str, $value) == 0)

return false;

return NULL;

}

function str_is_true($str) {

return (str_to_bool($str) === true);

}

function str_is_false($str) {

return str_to_bool($str) === false;

}

/* Test */

str_to_bool('false'); //return false

str_to_bool('vero'); // return true

str_to_bool('php'); //return null

str_is_true('php'); //return false

str_is_false('php'); //return false

?>

gherson 30-May-2006 07:33

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 23/30

To "foreach" over the characters of a string, first "preg_split" the string into an array:

<?php

$string="string";

$array = preg_split('//', $string, ‐1, PREG_SPLIT_NO_EMPTY);

foreach($array as $char) print($char."<br/>");

?>

This outputs:

s

tr

i

n

g

daniel dot oconnor at gmail dot com  09-Feb-2006 06:42

Dangers with References

<?php

$months = array("Jan", "Feb", "March");

foreach ($months as &$month) {

  $month .= "Beep";

}

print_r($months);

foreach ($months as $month) {

  printf("%s\n", $month);

}

?>

Because $month is a reference to $months[2], iterating again with the same varible name causes

$months[2] to be overwritten! Oh no!

Ouput:

Array

(

[0] => JanBeep

[1] => FebBeep

[2] => MarchBeep

)

JanBeep

FebBeep

FebBeep

RabidDog 17-Jan-2006 10:17

Pretty weird but for future reference

<?php

//doesn't multiply the last value

foreach ($ar as &$v){

  $v *= 2;

}

foreach($ar as $v){

echo $v. "<br>";

}

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 24/30

//works fine

foreach ($ar as &$o){

  $o *= 2;

}

foreach($ar as $v){

echo $v. "<br>";

}

?>

 janezr at jcn dot si  10-Nov-2005 09:06

If you want to "look‐ahead" values in an associative or non‐continuous array, this might help:

<?php

$myArray = {'one'=>1,'two'=>2,'five'=>5,'three'=>3}

$all_keys = array_keys($myArray);

foreach ( $all_keys as $key_index => $key ) {

  $value =& $myArray[$key];

  // $all_keys[$key_index+2] gives null if we go past the array boundary ‐ be carefull there

  $value2 =& $myArray[$all_keys[$key_index+2]] ;

...

}

?>

mikeb at tracersinfo dot com 26-Jul-2005 05:18

Using PHP5's foreach "as reference" can bite you!

Three guys in my office spent about a day chasing this one's tail, that was causing aberrant

behavior in the values of elements of an array. It turns out to be a consequence of the

nature of references, generally.

If you create a reference to a variable, all names for that variable (including the original)

BECOME REFERENCES. To paraphrase "The Highlander," if you want a name to OWN a piece of data,

"there can be only one."

To illustrate this point, consider the following code:

<?php

$f = array(

  0 => array('value' => 'three'),

  1 => array('value' => 'three')

);

foreach ( $f as $k => &$v ) {

  $v['value'] = 'one';

}

$a = $f;

$b = $f;

$b[0]['value'] = 'two';

$b[1]['value'] = 'two';

var_dump($a, $b);

?>

Upon execution, you will find that, although you would expect $a to contain two arrays with

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 25/30

'value' of 'one', $a and $b are identical ‐‐ i.e., the changes of []['value'] to 'two' have

happened in both arrays. But, upon further examination of the var_dumps, you will see that

both sets' elements [0] and [1] are preceded with "&": they are references!

The easy solution to this problem turns out to be: unset the foreach "as‐reference" variable

($v) at the bottom of your foreach loop. This allows the original variable (or array member)

to resume ownership of the value and dissolves its "reference‐ness".

magistrata at gmail dot com 13-Jul-2005 04:59I use this code to do a simple cleanup on information heading from an HTML form into a

database:

<?php

  foreach ($_POST as $key => $value) {

$$key = addslashes(trim($value));

}

?>

30-May-2005 05:17

How To Use References In Foreach Safely And Sanely In PHP 4.

There are two really really important points to remember about foreach and references:

1. foreach makes a copy

2. references (and unset!) work by directly manipulating the symbol table

In practice, this means that if you have an array of objects (or arrays) and you need to work

on them *in‐place* in a foreach loop, you have to do this:

<?php

foreach( $object_list as $id => $the_object ) {

  $the_object = & $object_list[$id]; // Re‐assign the variable to point to the real object

  ....

unset($the_object); // Break the link to the object so that foreach doesn't copy the next

one on top of it.

}

?>

This really works. I have used it in dozens of places. Yes, you need it all, including the

unset(). You will get extremely hard‐to‐find bugs if you leave out the unset().

Static.

flobee at gmail dot com 21-May-2005 08:32

be aware! take the note in the manual serious: "foreach operates on a copy of the specified

array"

when working with complex systems you may get memory problems because of all this copies of

arrays.

i love this function (easy to use) and use it more often than "for" or "while" functions but

now i have really problems on this and finally found the reason (which can be a mess to find

out)!

the sum of memory usage sometimes can be *2 than you really need.

Paul Chateau 17-May-2005 06:01

I had the same problem with foreach() and a recursiv function. If you don't want to spend

about 1 or 2 hours to solve this problem, just use for() loops instead of foreach().

Some Example:

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 26/30

<?php

$arr[] = array(1,"item1");

$arr[] = array(2,"item2");

$arr[] = array(1,"item3");

//$arr[] = ...

//doesn't work

function foo($x) {

global $arr; // some Array  foreach($arr as $value) {

if($value[0] == $x) {

echo $value[1]."\n";

  foo($value[0]);

}

}

}

//just use this

function foo($x) {

global $arr; // some Array

  for($i=0; $i < count($arr); $i++) {if($arr[$i][0] == $x) {

echo $arr[$i][1]."\n";

  foo($arr[$i][0]);

}

}

}

?>

Paul

gardan at gmx dot de 07-Oct-2004 07:21

(PHP 5.0.2)

Pay attention if using the same variable for $value in both referenced and unreferenced loops.

<?php

$arr = array(1 => array(1, 2), 2 => array(1, 2), 3 => array(1, 2));

foreach($arr as &$value) { }

foreach(array(1,2,3,4,5) as $value) { }

echo $test[3];

?>

What happens here is that after the first foreach() loop, you have in $value a reference to

the last element of $arr (here: array(1, 2)).

Upon entering the second foreach(), php assigns the value. Now value is assigned to where

$value (which is still a reference) points, that is, the last element of $arr.

Your output will be "5", not the expected "Array". To be on the safe side, unset($value)

before entering the next foreach().

scott at slerman dot net 18-Apr-2004 03:27

Apparently the behavior of foreach with classes changed in PHP5. Normally, foreach operates on

a copy of the array. If you have something like

<?php

foreach ($array as $value){

  $value = "foo";

}

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 27/30

?>

the original array will not be modified. However, testing this code on PHP5RC1

<?php

class foobar {

 

var $a;var $b;

 

function foobar(){

  $this‐>a = "foo";

  $this‐>b = "bar";

}

}

$a = new foobar;

$b = new foobar;

$c = new foobar;

$arr = array('a' => $a, 'b' => $b, 'c' => $c);

foreach ($arr as $e){

  $e‐>a = 'bah';

  $e‐>b = 'blah';

}

var_dump($arr);

?>

resulted in the following output:

array(3) {

["a"]=>

object(foobar)#1 (2) {

["a"]=>

string(3) "bah"

["b"]=>

string(4) "blah"

}

["b"]=>

object(foobar)#2 (2) {

["a"]=>string(3) "bah"

["b"]=>

string(4) "blah"

}

["c"]=>

object(foobar)#3 (2) {

["a"]=>

string(3) "bah"

["b"]=>

string(4) "blah"

}

}

It would seem that classes are actually passed by reference in foreach, or at least that

methods are called on the original objects.

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 28/30

 jazfresh at hotmail dot com  18-Feb-2004 06:50

There is a really really big pitfall to watch out for if you are using "foreach" and

references.

Recall this example:

<?php

$a = "Hello";

$b =& $a; // $b now refers to "Hello"

$b = "Goodbye"; // BOTH $a and $b now refer to "Goodbye"

?>

This also applies to the loop variable in a foreach construct. This can be a problem if the

loop variable has already been defined as a reference to something else.

For example:

<?php

// Create some objects and store them in an array

$my_objects = array();for($a = 0; $a < $num_objects; $a++) {

  $obj =& new MyObject();

  $obj‐>doSomething();

  $my_objects[] =& $obj;

}

// later on in the same function...

foreach($my_objects as $obj) { // Note that we are trying to re‐use $obj as the loop variable

  $obj‐>doSomethingElse();

}

?>

When the "for" loop exits, $obj is a reference to the last MyObject that was created, which is

also the last element in the "my_objects" array.

On every iteration, the foreach loop will do the equivalent of:

<?php

$obj = $my_objects[$internal_counter++];

?>

$obj will now refer to the appropriate element in the array.

But recall the reference example at the top. Because $obj was already defined as a reference,any assignment to $obj will overwrite what $obj was referring to. So in other words, on every

foreach loop iteration, the last element in the array will be overwritten with the current

array element.

To avoid this problem, either use a differently named loop variable, or call "unset()" on the

loop variable before you begin the foreach().

It would be more intuitive PHP unset() the loop variable before a foreach began, maybe they'll

put that in a later version.

andy at barbigerous dot net 06-Feb-2004 06:05

For dual iteration, the internal pointers may need resetting if they've been previously used

in a foreach.

<?PHP

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 29/30

for(

  $someArray1.reset(),

  $someArray2.reset();

list(, $someValue1 ) = each( $someArray1 ) ,

list(, $someValue2 ) = each( $someArray2 )

;

) {

echo $someValue1;

echo $someValue2;

}

?>

php at electricsurfer dot com 22-Apr-2003 08:33

[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';

}

?>

ian at NO_SPAM dot verteron dot net 01-Jan-2003 11:29Note that foreach is faster than while! If you can replace the following:

<?php

reset($array);

while(list($key, $val) = each($array))

{

  $array[$key] = $val + 1;

}

?>

...with this (although there are functional differences, but for many purposes this

replacement will behave the same way)...

<?php

foreach($array as $key => $val)

{

  $array[$key] = $val + 1;

}

?>

You will notice about 30% ‐ 40% speed increase over many iterations. Might be important for

those ultra‐tight loops :)

17-Sep-2002 04:06

"Also note that foreach operates on a copy of the specified array, not the array itself,

therefore the array pointer is not modified as with the each() construct and changes to the

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php

de 30 29-07-2011 12:31

8/4/2019 PHP_ Foreach - Manual

http://slidepdf.com/reader/full/php-foreach-manual 30/30

array element returned are not reflected in the original array."

In other words, this will work (not too expected):

<?php

foreach ($array as $array) {

  // ...

}

?>

While this won't:

<?php

while (list(, $array) = each($array)) {

  // ...

}

?>

 

Copyright © 2001-2011 The PHP Group

All rights reserved.

P: foreach - Manual http://www.php.net/manual/es/control-structures.foreach.php