2

Take a look to this code, and help me to understand the result

$x = array('hello', 'beautiful', 'world');
$y = array('bye bye','world', 'harsh');

foreach ($x as $n => &$v) { }

$v = "DONT CHANGE!";

foreach ($y as $n => $v){ }

print_r($x);
die;

It prints:

Array
(
    [0] => hello
    [1] => beautiful
    [2] => harsh
)

Why it changes the LAST element of the $x? it just dont follow any logic!

3
  • 2
    It is worth noting that there is zero benefit to using references in day to day code unless you understand all of the pitfalls and side-effects. Commented Nov 30, 2012 at 18:31
  • I was using with big arrays to use less memory usage. The solution I guess is to use unset after the foreach... to break the reference. Commented Nov 30, 2012 at 18:35
  • PHP variables are copy-on-write. There is no memory benefit to using references in this way. Commented Nov 30, 2012 at 18:36

3 Answers 3

4

After this loop is executed:

foreach ($x as $n => &$v) { }

$v ends up as a reference to $x[2]. Whatever you assign to $v actually gets assigned $x[2]. So at each iteration of the second loop:

foreach ($y as $n => $v) { }

$v (or should I say $x[2]) becomes:

  • 'bye bye'
  • 'world'
  • 'harsh'
Sign up to request clarification or add additional context in comments.

2 Comments

Ok, that makes sense, but shouldnt php remove the reference if using it in a foreach? I always like to use $v as my value and if i pass it as reference all my previous used arrays got broken. Its the first time I notice this beacause im working in a script without OOP. The only way to make it work is to call unset($v) directly after the first foreach
This is the expected behavior. See the last line of @inhan answer where he has mentioned a good practice in such situations.
4
// ...
$v = "DONT CHANGE!";
unset($v);
// ...

because $v is still a reference, which later takes the last item in the last foreach loop.

EDIT: See the reference where it reads (in a code block)

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

1 Comment

Thanks you so much for the link to the reference, there is a WARNING note also that clarifies this.
0

Foreach loops are not functions.An ampersand(&) at foreach does not work to preserve the values like at functions. So even if you have $var in the second foreach () do not expect it to be like a "ghost" out of the loop.

1 Comment

please avoid using abbreviations in sentences

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.