DevMoutarde
DevMoutarde

Reputation: 597

Can someone explain me this behaviour (PHP, foreach)

So I've come through this quite a lot of time, but Ive never been able to really understand it. Its taken straight from the php.net doc, its about foreach loop :

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

At some point php.net says you have to be careful because :

Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset(). Otherwise you will experience the following behavior:

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)

// without an unset($value), $value is still a reference to the last item: $arr[3]

foreach ($arr as $key => $value) {
    // $arr[3] will be updated with each value from $arr...
    echo "{$key} => {$value} ";
    print_r($arr);
}
// ...until ultimately the second-to-last value is copied onto the last value

// output:
// 0 => 2 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 2 )
// 1 => 4 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 4 )
// 2 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
// 3 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
?>

Whats really going on here? Is there a logic behind that (even a wrong logic since its not the expected behaviour)? But I dont actually understand it, can someone explain whats really going on?

To me it should have been :

// output:
// 0 => 2 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 8 )
// 1 => 4 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 8 )
// 2 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 8 )
// 3 => 8 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 8 )

Since it says the last array element remain (and the last value for array[3] was 8)... I just don't get it. Thanks for the help.

Upvotes: 3

Views: 80

Answers (1)

Hưng ho&#224;ng
Hưng ho&#224;ng

Reputation: 356

Follow me:

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)

// without an unset($value), $value is still a reference to the last item: $arr[3]

So $arr[3]is the reference.//Reference of a $value and the last array element remain even after the foreach loop

foreach ($arr as $key => $value) {
    // $arr[3] will be updated with each value from $arr...
    echo "{$key} => {$value} ";
    print_r($arr);
}
// ...until ultimately the second-to-last value is copied onto the last value

// output:
// 0 => 2 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 2 )
// 1 => 4 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 4 )
// 2 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
// 3 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
?>

$arr[3] and $value are pointing to the same place.

when $key = 0, $value =2 => $value = $arr[3]=2
when $key = 1, $value =4 => $value = $arr[3]=4
when $key = 2, $value =6 => $value = $arr[3]=6

this time ,$arr is now array(2, 4, 6, 6)

Upvotes: 1

Related Questions