Don't worry I know how variable work internaly into Zend Engine ( for those
who want more info, Derick Rethan's got a good pdf file explaining that
process here :
http://derickrethans.nl/files/phparch-php-variables-article.pdf , Derick, if
you here us, feel free to come in that conversation ;-) )

But as said, that is an internal PHP behavior that, in my opinion, should be
explained in the documentation.
Now consider this :

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

next($b); // go to the second key of $b

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

   if (current($a) == current($b)){ // I want you to stop on the second key
of $b
       var_dump(current($b)); // will never get echoed, as current($a)
always returns String"One"
       break;
   }

}
?>

Due to COW, using current($a) makes PHP making a "real" copy of $a array to
work on it, and current($a) is always at its first place ( String"One")
because PHP works on the "real" copy, and its own array iterator. In that
example, the if condition will never be satisfied.
Ok let's make it funnier now :

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

next($b);

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

   if (current($a) == current($b)){
       var_dump(current($b)); // works : outputs String"Two"
       break;
   }

}

var_dump(current($a)); // output String"Two"
?>

Aha, now if I hold a reference to $a variable ($c here ), it looks like COW
doesn't show the same behavior as before.
Foreach seems to keep working on a "lazy" copy of $a, and so it moves the
real $a internal iterator as shown here. The if condition is verified and
the last script line clearly shows that $a internal pointer has been
manipulated by the foreach loop.


We see here that working on internal iterators using foreach is not really
recommanded. I have never needed to do that in a real developpement as well,
I'm just experimenting PHP behavior, but I think that the official
documentation should warn users about such behaviors.

For information : it's actually tested, for me, on PHP 5.2.3 running on a
Windows server. Error Reporting is set to E_ALL.

cheers.
Julien (French)

2007/6/23, Nathan Nobbe <[EMAIL PROTECTED]>:

> On 6/23/07, Robert Cummings < [EMAIL PROTECTED]> wrote:
> Regardless of additional documentation or not, I think it's rather poor
> choice of programming style to mix the foreach construct with the older,
> lower level, internal array manipulation and probing functions. I think
> that is what should be documented since you just might get weird
> results :)

i agree; at least i have never had a need to determine the current index
of the internal array pointer in nearly 3 years working w/ php.
although it is somewhat interesting to experiment w/ the language to see
how it behaves :)

-nathan


On 6/23/07, Robert Cummings < [EMAIL PROTECTED]> wrote:
>
> On Sat, 2007-06-23 at 15:15 -0400, Nathan Nobbe wrote:
> >
> > in summary, COW or not; i think the documentation could be revised a
> bit to
> > clarify these subtleties.
>
> Regardless of additional documentation or not, I think it's rather poor
> choice of programming style to mix the foreach construct with the older,
> lower level, internal array manipulation and probing functions. I think
> that is what should be documented since you just might get weird
> results :)
>
> Cheers,
> Rob.
> --
> .------------------------------------------------------------.
> | InterJinn Application Framework - http://www.interjinn.com |
> :------------------------------------------------------------:
> | An application and templating framework for PHP. Boasting  |
> | a powerful, scalable system for accessing system services  |
> | such as forms, properties, sessions, and caches. InterJinn |
> | also provides an extremely flexible architecture for       |
> | creating re-usable components quickly and easily.          |
> `------------------------------------------------------------'
>
>

Reply via email to