Home » Php » PHP Bug or my misunderstanding of the language?

PHP Bug or my misunderstanding of the language?

Posted by: admin July 12, 2020 Leave a comment

Questions:

This is the code that I don’t understand (as the output).

<?php
$x = ['test1', 'test2', 'test3', 'test4'];
echo "First FOREACH\n";
foreach ($x as &$y)
{
    echo $y."\n";
}
echo "\n\nSecond FOREACH\n";
foreach ($x as $y)
{
    echo $y."\n";
}

?>

Output:

First FOREACH
test1
test2
test3
test4

Second FOREACH
test1
test2
test3
test3

PS: I’m running it under:

php -v
PHP 5.6.11-1ubuntu3.1 (cli) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
How to&Answers:

After the first foreach statement you have $y pointing to the last array item:

$x = ['test1', 'test2', 'test3', 'test4'];
$y =& $x[3];

Whenever you assign a value to $y original array will be modified.

When second foreach begins, on every iteration next value from $x is put into $y. So on every iteration original array will look like:

// first iteration
$x = ['test1', 'test2', 'test3', 'test1'];
// second iteration
$x = ['test1', 'test2', 'test3', 'test2'];
// third iteration
$x = ['test1', 'test2', 'test3', 'test3'];
// fourth iteration
$x = ['test1', 'test2', 'test3', 'test3'];

Answer:

It’s more of a feature, it’s documented in the foreach manpage

Warning
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

There are some relevant comments on the manpage, here’s one of them
http://php.net/manual/en/control-structures.foreach.php#111688

More info on how this happens here http://schlueters.de/blog/archives/141-References-and-foreach.html

Answer:

I’d say you get something like.

First FOREACH
test1 test2
Second FOREACH
test1
test1

Because you are using the & with your $y in the first foreach so you make $y a reference to $x, the whole array $x. And $y will stay a reference until you unset it.

So…
Because you reuse $y in the next foreach, PHP is setting $x twice to the first element of $y being ‘test1’. $x will be [‘test1′,’test1’].

Always be careful while using references and always unset them when you no longer need them.

Answer:

It happened because of your first loop, $y is still a reference to the last array item, so it’s overwritten each time.

When you use reference in loop, its recommended to destroy it by using unset() function.

For suppose, when you create a Global variable, it means you are creating a reference.

And one more example, when we use $this keyword within an object, we are creating the reference of this object instead of copy again.

Answer:

Ok i think it happens like this:

when your first loop is done. the last element in the array is still referenced with the variable $y

think of your array like this when the first loop is done :

['test1', 'test2', 'test3', &'test4']

Note that i have inserted a & at the last element because it is reference with the variable $y

Now when the second loop begins. Each element in $x will be referenced as $y and remember in your array $x the last element is still being referenced by variable $y from the loop.

So the last element in array $x is modified in each iteration of the second loop. as $y

['test1', 'test2', 'test3', &'test1'] <-- $y as being first element, notice that the last element is also $y
['test1', 'test2', 'test3', &'test2'] $y being 'test2'
['test1', 'test2', 'test3', &'test3'] $y as 'test3'
['test1', 'test2', 'test3', &'test3'] $y being the last element which is 'test3'