On Sat, 2007-06-23 at 19:15 +0200, Julien Pauli 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 ? The answers lies in the following although it's not terribly clear why the behaviour is as it is: **** Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. Therefore, the array pointer is not modified as with the each() construct, and changes to the array element returned are not reflected in the original array. However, the internal pointer of the original array is advanced with the processing of the array. Assuming the foreach loop runs to completion, the array's internal pointer will be at the end of the array. **** If you understand how PHP copies values then it makes sense. Let me explain... When the foreach loop is entered $a is copied for use by the foreach itrator; however, a copy in PHP is a lazy copy. This means that the the copy is still referencing the original value, and this is why the internal pointer is still advanced. Now what probably happens is that when the current() function is used on $a something internally tells the PHP engine that a modification has occurred, as such the COW (copy on write) policy comes into effect. This essentially differentiates a copy since a change is occurring such that there is now a real and distinct copy. So internally $a had the internal pointer reset on entry to the foreach loop, current() somehow invokes the COW policy causing a real copy to be generated, and then the foreach continues merrily forward with the real copy leaving current() to work with the original copy. Hope that make sense to you :) For what it's worth, COW is why if you have a variable consuming 100 megabytes stored in $x and you assign it to $y that you don't end up consuming 200 megs of memory. Now if $x is a string and you change append one character to $y, you should find that now you are consuming 200 megs of memory since a real copy is generated when the change is incurred. This is an optimization strategy. 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. | `------------------------------------------------------------' -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php