9

On a foreach loop, it seems PHP reads the whole array at the beginning, so if you suddenly need to append new items to the array they won't get processed by the loop:

$a = array (1,2,3,4,5,6,7,8,9,10);

foreach ($a as $b)
    {
        echo " $b ";
        if ($b ==5) $a[] = 11;
    }

only prints out: 1 2 3 4 5 6 7 8 9 10

Henry
  • 1,374
  • 2
  • 14
  • 24

4 Answers4

24

Just create a reference copy of the array you are looping

$a = array(1,2,3,4,5,6,7,8,9,10);
$t = &$a; //Copy
foreach ( $t as $b ) {
    echo " $b ";
    if ($b == 5)
        $t[] = 11;
}

Or Just use ArrayIterator

$a = new ArrayIterator(array(1,2,3,4,5,6,7,8,9,10));
foreach ( $a as $b ) {
    echo "$b ";
    if ($b == 5)
        $a->append(11);
}

Output

 1 2 3 4 5 6 7 8 9 10 11

See Live Demo

Baba
  • 94,024
  • 28
  • 166
  • 217
1

On the spirit of its-ok-to-ask-and-answer-your-own-questions, this is the best workaround I have found: convert it to a while loop.

$a = array (1,2,3,4,5,6,7,8,9,10);
$i = 0;
while ($i < count($a))
    {
        $b =  $a[$i];
        echo " $b ";
        if ($b ==5) $a[] = 11;
        $i++;
    }

Not it properly gives out 1 2 3 4 5 6 7 8 9 10 11

Community
  • 1
  • 1
Henry
  • 1,374
  • 2
  • 14
  • 24
  • 2
    The only poblem with this might be that count($a) is executed every time the loop is run as well which can be a performance hit. I'm not too sure how foreach handles this though. – Alexander Varwijk Aug 01 '13 at 17:24
  • 2
    You could make the while more compact with for `for ($i = 0; $i < count($a); $i++) {` – Jason S Mar 05 '14 at 09:48
  • 3
    @AlexanderVarwijk the whole premise is that the size of $a may change anytime, so counting it at each iteration is the only way to find out – Henry Mar 08 '14 at 01:17
0

A simple way to do it is to create a second array which will keep the old array and while looping you can add new values there .

At the end of the loop the new array will have the old one + new inserted values

-2
$arr = [1,2,3];

while ($el = current($arr)) {
    var_dump($el);
    $arr[] = 123; // infinite loop
    next($arr);
}
zim32
  • 2,561
  • 1
  • 24
  • 31