Re: foreach() using current() strange beahvior

From: Date: Sun, 24 Jun 2007 14:05:26 +0000
Subject: Re: foreach() using current() strange beahvior
References: 1 2 3 4  Groups: php.general 
Request: Send a blank email to php-general+get-257723@lists.php.net to get a copy of this message
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 <quickshiftin@gmail.com>:
On 6/23/07, Robert Cummings < robert@interjinn.com> 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 < robert@interjinn.com> 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.          |
`------------------------------------------------------------'


« previous php.general (#257723) next »