PHP behavior and arrays pointers
arrays, php, pointers
Solution
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.
Problem
I was reading the PHP manual (specifically the `each()` function) and came across the following warning: Caution Because assigning an array to another variable resets the original array's pointer, our example above would cause an endless loop had we assigned $fruit to another variable inside the loop. And an example: ``` <?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry'); reset($fruit); while (list($key, $val) = each($fruit)) { echo "$key => $val\n"; } ?> ``` Okay. It makes sense. But I decided to do a simple test: ``` <?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry'); foreach ($fruit as $key => $name) { printf("[%s] => [%s]\n", $key, $name); } $fruit2 = $fruit; echo current($fruit); ?> ``` The result is expected: the pointer has been reset. My question is if the pointer is reset only after the end of the array? For example: ``` <?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry'); foreach ($fruit as $key => $name) { printf("[%s] => [%s]\n", $key, $name); } reset($fruit); next($fruit)."\n"; $fruit2 = $fruit; echo current($fruit); ?> ``` The pointer remains in the second array element `('b' => 'banana')`. This behavior is characteristic of language? Thank you and sorry for bad English.