This behavior is characteristic of language?
The meaning of "pointer" in PHP arrays is not the same as the general meaning of "pointer" (in C/C++ or other languages that gives the programmer direct access to memory).
There are no pointers in PHP. The array data type keeps internally a cursor inside the list of values it contains. It is called the internal pointer of the array and it is modified by functions reset()
, next()
, prev()
, end()
, each()
and maybe others. It can be used to iterate over the array like this:
$array = array(1, 2, 3);
while (list($key, $val) = each($array)) {
echo($key.' => '.$val."\n");
}
There is no reliable way to iterate the array using next()
or prev()
because they return FALSE
when there are no more elements to iterate but they also return FALSE
when the value FALSE
is stored as an element in the array.
They could be useful if you need to analyze only several items from the beginning (or end) of the array. F.e. let's say we have an array of integers returned by a function and we need to get the first value that is not zero.
But this goal can be accomplished even easier using foreach()
:
$array = array(0, 0, 0, 2, 0, 1, 0, 3);
foreach ($array as $val) {
if ($val != 0) {
break;
}
}
echo($val); // prints "2"
or array_shift()
:
$array = array(0, 0, 0, 2, 0, 1, 0, 3);
do {
$val = array_shift($array);
if ($val != 0) {
break;
}
} while(count($array));
echo($val); // prints "2"
The result is expected: the pointer has been reset. My question is if the pointer is reset only after the end of the array?
The documentation of foreach()
is wrong. Maybe it was correct on PHP 3 and PHP 4 but I think since the introduction of iterators in PHP 5 the behaviour of foreach()
changed (to better).
It says:
When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
As foreach relies on the internal array pointer, changing it within the loop may lead to unexpected behavior.
A simple test contradicts this statement:
$array = array(1, 3, 5, 7, 9);
foreach ($array as $val1) {
foreach ($array as $val2) {
echo('$val1='.$val1.'; $val2='.$val2.'; ');
}
echo("\n");
}
It works without problems. It should not work if foreach()
is using the internal array pointer. It probably creates a copy of the pointer.
You can also try to use current()
, next()
, prev()
or reset()
inside the foreach()
and you will get surprising and sometimes inconsistent results.
You better use foreach()
to iterate over the arrays and do not rely on the internal pointer in any way.
The functions reset()
and end()
are, however, very handy when you need to get the first and the last element of the array without worrying about the keys.