23
To clarify, this question is not about when the foreach
is used or differs from it to other loops of repetition, but about the functioning of foreach
in itself.
In the documentation, little is said about how exactly the foreach
works, paying more attention to how to use it. Some loose sentences seem to be an attempt to detail a little better, but out of a specific context they end up not aggregating much.
Quoting:
In PHP 7, foreach does not use the array’s internal pointer.
That is, we can freely change the internal pointer of the array within the loop of foreach
without interfering with its execution.
Test 1: Restarting the internal pointer of the array every iteration does not restart the loop
$arr = range(1, 5);
foreach($arr as $item) {
echo $item, PHP_EOL;
reset($arr);
}
See working on Repl.it | Ideone
Even if you restart the internal pointer array the loop is normally finished.
To directly modify elements of an array within a loop, preceded $value with &.
Which, at first, indicates that the foreach
does not create a copy of array to be used during the loop, as the reference in the element would be a reference to the item in the copy and no longer 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 element array original and not for a copy of it
$arr = range(1, 5);
foreach($arr as &$item) {
$item *= 2;
}
print_r($arr);
See working on Repl.it | Ideone
However, we can see in practice that the array used by the repeating structure is not exactly the array as we can freely alter the array without interfering with the bond.
Test 3: Changing the array original within the foreach
does not change the behavior of the loop
$arr = range(1, 5);
foreach($arr as $item) {
echo $item, PHP_EOL;
$arr[] = $item;
}
See working on Repl.it | Ideone
In this example, with each iteration we add a new element at the end of array. If the foreach
use the reference of $arr
, 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 by
foreach
is not the pointer of array; - Test 2 would show that the
foreach
does not make a copy of the array, because the reference points to the element of array original, not a array copying; - Test 3 shows that the
foreach
makes, in fact, a copy of the array, as changes made within the loop are not reflected in the array original;
Tests 2 and 3, mainly, are at first contradictory, because one behaves as a copy, while the other does not.
So the question is, how does foreach
of PHP works?
If the behavior of the structure differs between versions of the language and compares them would make the answer too large, it is accepted that it be answered about its functioning in the most current version.
This question was asked on the basis of a self-doubt, aided by a chat discussion and inspired by the question How does PHP 'foreach' Actually work?
– Woss
The accepted answer from the English forum, from the link in your comment, is not good enough for you?
– Leonardo Alves Machado
@Leonardoalvesmachado the idea is precisely to bring this type of content (or better, even) to our site, in Portuguese.
– Woss
Mmm, I get it... It would really enrich the site...
– Leonardo Alves Machado
@Leonardoalvesmachado, moreover, many will not understand Soen’s reply because it is in English. Anderson’s initiative is good and I look forward to a response in Portuguese! :)
– user60252