To clarify, this question is not about when foreach
is used or what its differences are for other repetition loops , but rather on the operation of foreach
itself.
In documentation , little is said about exactly how foreach
works, if not more, how to use it. Some loose phrases seem to be an attempt to detail a little better, but out of a specific context they end up not adding much.
To quote:
In PHP 7, foreach does not use the array's internal pointer.
That is, we can freely change the internal array pointer within the foreach
loop without interfering with its execution.
Test 1: Restarting the internal array pointer at each iteration does not cause the loop to restart
$arr = range(1, 5);
foreach($arr as $item) {
echo $item, PHP_EOL;
reset($arr);
}
See working at Repl.it | Ideone
Even restarting the internal pointer of the array loop terminates normally.
To directly modify elements of an array within a loop, precede $ value with &.
Which, in principle, indicates that foreach
does not create a copy of array to use during the loop, since the reference in the element would be a reference to the element in the copy rather than in the array original. But what we see in practice is that the reference points to the original element.
Test 2: Element reference points to the original array element and not to a copy of it
$arr = range(1, 5);
foreach($arr as &$item) {
$item *= 2;
}
print_r($arr);
See working at Repl.it | Ideone
However, we can see in practice that the array used by the repeat structure is not exactly the original array , since we can freely change the array > without interfering with the loop.
Test 3: Changing the original array within foreach
does not change loop behavior
$arr = range(1, 5);
foreach($arr as $item) {
echo $item, PHP_EOL;
$arr[] = $item;
}
See working at Repl.it | Ideone
In this example, at each iteration we add a new element at the end of the array . If foreach
used the reference of $arr
itself, the loop would be infinite, but what happens in practice is that only the original items are iterated.
In short:
Test 1 shows that the pointer used byforeach
is not the pointer to the array ;
foreach
does not make a copy of array , because the reference points to the original array element, not an array of copy; foreach
does indeed copy a array , because changes made inside the loop are not reflected in the original array / li>
Tests 2 and 3 are mainly contradictory, since one behaves like a copy while the other does not.
So the question is: how does foreach
of PHP work?