Re: foreach() using current() strange beahvior

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Julien,

i reproduced your experiment and got a different result on the first one.  i
found that the internal pointer does not seem to be affected if there is a
check on the index of the internal pointer during iteration, but if there is
no check on the index during iteration the
pointer seems to get incremented.  needless to say this is rather strange. *
*also *turadg at berkeley dot edu* describes his experience w/ this issue on
the foreach documentation<http://www.php.net/manual/en/control-structures.foreach.php>in
the user comments section.  he found that by aliasing the original
array
variable the behavior described in the documentation is realized.
i have summarized these findings in the following code segment, which you
can run yourself as well for corroboration

<?php
/// initialize $a to an array w/ 3 strings
$a = array('one', 'two', 'three');
echo 'experiment 1a.' . PHP_EOL;
/// iterate over a checking the value of the internal pointer during each
iteration
foreach($a as $k => $v) {
if(current($a) != false) {
echo current($a) . PHP_EOL;
} else {
var_dump(current($a));
}
}
/// check the internal pointer after iteration is complete (should be
pointing at last index)
if(current($a) != false) { // strangely this is still the first index of the
array
echo current($a) . PHP_EOL;
} else {
var_dump(current($a));
}

echo 'experiment 1b.' . PHP_EOL;
/// another run through the array where there is no check on the value of
the internal pointer during each iteration
foreach($a as $k => $v) {}
/// check the internal pointer after iteration this time
if(current($a) != false) { // and now the pointer is the last index of the
array (as expected)
echo current($a) . PHP_EOL;
} else {
var_dump(current($a));
}

echo 'experiment 2a.' . PHP_EOL;
//// ALIAS THE ORIGINAL ARRAY VARIABLE
$a2 =& $a; // create an alias of $a for further experimentation
foreach($a as $k => $v) { // first experiment
if(current($a) != false) { // now the internal index is being incremented
echo current($a) . PHP_EOL;
} else {
var_dump(current($a));
}
}

if(current($a) != false) { // and here the internal pointer is the last
index
echo current($a) . PHP_EOL;
} else {
var_dump(current($a));
}

echo 'experiment 2b.' . PHP_EOL;
/// second experiment (no checking of the index during iteration)
foreach($a as $k => $v) {}
if(current($a) != false) { // and the internal pointer is the last index
echo current($a) . PHP_EOL;
} else {
var_dump(current($a));
}
?>

/// this is the output on my machine
experiment 1a.
one
one
one
one
experiment 1b.
bool(false)
experiment 2a.
two
three
bool(false)
bool(false)
experiment 2b.
bool(false)

in summary, COW or not; i think the documentation could be revised a bit to
clarify these subtleties.

-nathan


On 6/23/07, Julien Pauli <doctorrock83@xxxxxxxxx> wrote:

Please consider this code :

<?php
$a = array("One","Two","Three");

foreach ($a AS $k=>$v) {
}

var_dump(current($a));
// outputs boll(false);

that's expected as foreach moves the internal array pointer, it's
documented.

now consider this :

<?php
$a = array("One","Two","Three");

foreach ($a AS $k=>$v) {
current($a);
}

var_dump(current($a));
// outputs string("One");

When using the internal pointer just by calling current() (so not moving
it), the output of the foreach loop has changed ...
Can someone explain that ?

regards.


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux