Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php foreach- Why it doesn't override the array value while iterating?

Tags:

foreach

php

I have a doubt in php foreach iteration.

Please look my below code.

CODE :

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

    echo '$arr value : '. $arr;

    echo '<br>';

    foreach($arr as $arr){
        echo $arr.'<br>';
    }
    echo '$arr value : '. $arr;

OUTPUT :

$arr value : Array
1
2
3
$arr value : 3

While iterating array i used same array name to value key foreach($arr as $arr) but it works fine. How it is working?.

Why it doesn't override the array value while iterating?

I want to know how foreach iteration is working.

Please Help me!

Thanks in advance Logan

like image 662
Logan Avatar asked Sep 07 '12 06:09

Logan


3 Answers

Why it doesn't override the array value while iterating?

foreach will work on a copy of the original array so things you change in the foreach loop will not change the values you are looping over.

like image 169
Emil Vikström Avatar answered Nov 16 '22 14:11

Emil Vikström


PHP uses a copy on write or lazy copy mechanism with reference counting for memory handling.

In the first stage of foreach iteration, $arr is "soft copied" (no actual copy, but only the refcount of the zval of $array is increased). checkout variable container and label of PHP variables.

In our case,

  • it first keep a reference to actual $arr variable, and the first value of array is fetched from the reference point.
  • For later use first array element is assigned to second $arr foreach($arr as $arr)
  • In the next iteration, second array value is fetched from previously saved reference point, and that value is assigned to same $arr and continues.
  • As value of $arr is changed inside loop, you cannot print that array outside loop using $arr variable.

Hope you can understand...

For an in-depth study checkout http://www.php.net/manual/en/internals2.opcodes.fe-fetch.php and http://www.php.net/manual/en/internals2.opcodes.fe-reset.php

Interestingly you can play with this too...

current() inside a foreach loop will always returns the same element!!!

Code

$source = array(10, 20, 30);
foreach ($source as $value) {
    echo 'Value is ', $value, ', and current() is ', current($source), '<br>';
}

Output

Value is 10, and current() is 20
Value is 20, and current() is 20
Value is 30, and current() is 20
like image 45
rajukoyilandy Avatar answered Nov 16 '22 14:11

rajukoyilandy


foreach ($arr as $arr) {
    // code
}

This may be confusing to you because your mental model of how this works is:

  1. PHP takes the current element out of $arr and advances the array pointer
  2. it assigns the value to $arr
  3. it executes // code
  4. it repeats from step one

What it actually does though is this (or at least an approximate simplification of it):

  1. PHP starts the foreach operation, taking the array value that is associated with $arr
  2. it puts this array somewhere internally, let's say a var iterator
  3. it takes the current element from var iterator and advances the iterator
  4. it assigns the value it took to $arr in your script
  5. it executes // code
  6. it repeats from step 3

In other words, it does not take the next value from $arr on every iteration, it only used this once to get the initial iterator. The actual thing that it iterates over is stored internally and is not associated with $arr anymore. That means $arr is free for other purposes in your script and PHP is happy to reuse it on each iteration. After the loop is done, the last element remains in $arr.

If you know anonymous functions, maybe this illustrates better why this works the way it works:

foreach($arr, function ($arr) {
    // code
});

The implementation of such a foreach function can be simply this:

function foreach(array $array, callable $code) {
    while (list(, $value) = each($array))  {
        $code($value);
    }
}
like image 1
deceze Avatar answered Nov 16 '22 13:11

deceze