ID: 42316 User updated by: titerm at lfdj dot com Reported By: titerm at lfdj dot com -Status: Feedback +Status: Open Bug Type: SPL related Operating System: Windows PHP Version: 5.2.3 New Comment:
I did my test on 5.2.3 release on window and solaris. I don't understand why you say original array is not modified since i'm using offsetSet function, it should modified $arr and it does. If i init $arr with $data1 and $data2 like this, only branch one is altered. $data1['one'] = 'ORG'; $data2['one'] = 'ORG'; $arr = array ( 'branch1' => $data1, 'branch2' => $data2, ); Previous Comments: ------------------------------------------------------------------------ [2007-08-16 13:47:51] [EMAIL PROTECTED] Since the iterator does not modify original array, this is the expected result of your script (and what I get using latest CVS build): array(2) { ["branch1"]=> array(1) { ["one"]=> string(3) "ORG" } ["branch2"]=> array(1) { ["one"]=> string(3) "ORG" } } ------------------------------------------------------------------------ [2007-08-16 12:11:48] titerm at lfdj dot com Create a ArrayIterator on branch1. Alter the leaf by using iterator. Leave on branch2 are affected too. Simplified reproduce code. $data['one'] = 'ORG'; $arr = array ( 'branch1' => $data, 'branch2' => $data, ); $iterator = new ArrayIterator($arr['branch1']);; $iterator->offSetSet($iterator->key(), 'ALTER' ); var_dump($arr); Expected result array 'branch1' => array 'one' => string 'ALTER' (length=5) 'branch2' => array 'one' => string 'ORG' (length=3) Actual result array 'branch1' => array 'one' => string 'ALTER' (length=5) 'branch2' => array 'one' => string 'ALTER' (length=5) ------------------------------------------------------------------------ [2007-08-16 10:45:42] [EMAIL PROTECTED] What if you didn't pay attention to the internals like refcount but only for actual results? Can you come up with a short and simple example of what actually doesn't work? ------------------------------------------------------------------------ [2007-08-16 08:32:05] titerm at lfdj dot com I have simplified the reproduce code to much. Sorry it should be $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr['l1'])); foreach($iterator as $leaf) { $iterator->offSetSet($iterator->key(), 'ALTER' ); } Expected result array(3) refcount(2){ ["l1"]=> array(1) refcount(1){ ["one"]=> array(1) refcount(1){ ["two"]=> string(5) "ALTER" refcount(1) } } ["l2"]=> array(1) refcount(1){ ["one"]=> array(1) refcount(1){ ["two"]=> string(3) "ORG" refcount(2) } } ["l3"]=> array(1) refcount(1){ ["one"]=> array(1) refcount(1){ ["two"]=> string(3) "ORG" refcount(1) } } } Actual Result array(3) refcount(2){ ["l1"]=> array(1) refcount(3){ ["one"]=> array(1) refcount(1){ ["two"]=> string(5) "ALTER" refcount(1) } } ["l2"]=> array(1) refcount(1){ ["one"]=> array(1) refcount(1){ ["two"]=> string(3) "ORG" refcount(2) } } ["l3"]=> array(1) refcount(3){ ["one"]=> array(1) refcount(1){ ["two"]=> string(5) "ALTER" refcount(1) } } } ------------------------------------------------------------------------ [2007-08-16 08:18:32] titerm at lfdj dot com Description: ------------ When multiple entries of an array are initialized with a $base var array, new entries will increase refcount. Any modification of this new entries should decrease refcount. But if modification are done through a recursive Array Iterator, refcount works like it was reference, and all leaf are modified Reproduce code: --------------- // Reference var array $base['one']['two'] = 'ORG'; // Work array $arr = array ( 'l1' => $base, 'l2' => $base, 'l3' => $base, ); unset($base); // No need anymore of reference // Break refcount for level 2, level 1 and level 3 are still refcount $arr['l2']['one']['two'] = $arr['l2']['one']['two']; // Create an iterator on level 1 $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr['l1'])); // Alter leaf of level 1 $iterator->offSetSet($iterator->key(), 'ALTER' ); debug_zval_dump($arr); Expected result: ---------------- array(3) refcount(2){ ["l1"]=> array(1) refcount(1){ ["one"]=> string(5) "ALTER" refcount(1) } ["l2"]=> array(1) refcount(1){ ["one"]=> array(1) refcount(1){ ["two"]=> string(3) "ORG" refcount(1) } } ["l3"]=> array(1) refcount(1){ ["one"]=> string(3) "ORG" refcount(1) } } Actual result: -------------- array(3) refcount(2){ ["l1"]=> array(1) refcount(3){ ["one"]=> string(5) "ALTER" refcount(1) } ["l2"]=> array(1) refcount(1){ ["one"]=> array(1) refcount(1){ ["two"]=> string(3) "ORG" refcount(1) } } ["l3"]=> array(1) refcount(3){ ["one"]=> string(5) "ALTER" refcount(1) } } ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=42316&edit=1