Bug #17959 Updated: array reference problems

From: Date: Sat, 13 Jul 2002 22:30:00 +0000
Subject: Bug #17959 Updated: array reference problems
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-14100@lists.php.net to get a copy of this message
ID: 17959 Updated by: derick@php.net Reported By: pkeshish@yahoo.com -Status: Open +Status: Feedback Bug Type: Scripting Engine problem Operating System: linux PHP Version: 4.2.1 New Comment: Please provide a SHORT reproducing script. Derick Previous Comments: ------------------------------------------------------------------------ [2002-06-25 00:41:53] pkeshish@yahoo.com <?php // // There seems to be some issues with how array references // are handled by PHP, unless, my understanding of how // array()s and references to them are supposed to work is // seriously flawed. // // Unfortunately i don't have enough time on my hands to // dig through PHP sources. // // The source below seems to be a few very simple test-cases // pointing out the bug that's caused me enough grief. // Hopefully, someone can use this information in tracking // down the bug and eventually fixing it. // // The following issues can be duplicated on both // PHP Versions 4.1.2 and 4.2.1 // // I'm not much concerned about 'Case 1' as I am about // cases 3 and 4. They seem more serious problems. // ?> <? // -- Case 1 // This case demonstrates that $top['B']['B_b']['parent'] loses // the reference to parent array! // $top = array ( 'name' => 'top', 'parent' => null, 'A' => array ( 'name' => 'A', 'parent' => &$top, ), 'B' => array ( 'name' => 'B', 'parent' => &$top, 'B_b' => array ( 'name' => 'B_b', 'parent' => &$top['B'], ), ), ); ?> <pre> case 1: top: <? foreach ( $top as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <pre> top['A']: <? foreach ( $top['A'] as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <pre> top['B']: <? foreach ( $top['B'] as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <pre> top['B']['B_b']: <? foreach ( $top['B']['B_b'] as $k => $v ) { printf( " $k =&gt; $v\n" ); } // // What happened to $top['B']['B_b']['parent'] reference? // ?> </pre> <hr align="left" size="5" width="80%"> <? // -- Case 2 // This case shows a work around to above bug. // $top = array ( 'name' => 'top', //'parent' => null, 'A' => array ( 'name' => 'A', //'parent' => &$top, ), 'B' => array ( 'name' => 'B', //'parent' => &$top, 'B_b' => array ( 'name' => 'B_b', //'parent' => &$top['B'], ), ), ); $top['parent'] = null; $top['A']['parent'] = &$top; $top['B']['parent'] = &$top; $top['B']['B_b']['parent'] = &$top['B']; ?> <pre> case 2: top: <? foreach ( $top as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <pre> top['A']: <? foreach ( $top['A'] as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <pre> top['B']: <? foreach ( $top['B'] as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <pre> top['B']['B_b']: <? foreach ( $top['B']['B_b'] as $k => $v ) { printf( " $k =&gt; $v\n" ); } ?> </pre> <hr align="left" size="5" width="80%"> <pre> case 3: <? // -- Case 3 // This case demonstrates how change_ptr() function fails to actually // change the value of a global variable $ptr. // // Essentially 'global $ptr' seems to only be local to the function // scope and modifying its value seems to have no bearing on the // global variable $ptr that we are interested in!! // // Please note that the demonstrated behavior is inconsistant with // how $iref is treated. // $ptr = &$top; $i = 0; $iref = &$i; function change_ptr( $name ) { global $ptr; global $iref; $iref++; printf( " change_ptr($name) " ); if ( $ptr[$name] ) { $before_change = sprintf( "before: \$ptr['name'] = %s", $ptr['name'] ) . "\n " . sprintf( " \$GLOBALS['ptr']['name'] = %s", $GLOBALS['ptr']['name'] ); $ptr = &$ptr[$name]; $after_change = sprintf( "after: \$ptr['name'] = %s", $ptr['name'] ) . "\n " . sprintf( " \$GLOBALS['ptr']['name'] = %s", $GLOBALS['ptr']['name'] ); printf( "<font color=\"green\">CHANGED</font>:\n" ); printf( " %s\n %s", $before_change, $after_change ); } else printf( "<font color=\"red\">NO CHANGE!</font>" ); printf( "\n \$iref: $iref<br>\n" ); } change_ptr('B'); change_ptr('B'); // what is going on?? Why didn't previous call stick? ?> </pre> <hr align="left" size="5" width="80%"> <pre> case 4: <? // -- Case 4 // This case shows the expected behavior of 'Case 3'. // function change_ptr2( $name ) { global $iref; $iref++; printf( " change_ptr2($name) " ); if ( $GLOBALS['ptr'][$name] ) { $before_change = sprintf( "before: \$GLOBALS['ptr']['name'] = %s", $GLOBALS['ptr']['name'] ); $GLOBALS['ptr'] = &$GLOBALS['ptr'][$name]; $after_change = sprintf( "after: \$GLOBALS['ptr']['name'] = %s", $GLOBALS['ptr']['name'] ); printf( "<font color=\"green\">CHANGED</font>:\n" ); printf( " %s\n %s", $before_change, $after_change ); } else printf( "<font color=\"red\">NO CHANGE!</font>" ); printf( "\n \$iref: $iref<br>\n" ); } change_ptr2('B'); change_ptr2('B'); // good! no change change_ptr2('B_b'); change_ptr2('parent'); // Back to $top['B'] change_ptr2('parent'); // Back to $top change_ptr2('A'); // This call will cause a problem soon! change_ptr2('parent'); change_ptr2('B'); change_ptr2('B_b'); // And just as we were doing so well ... change_ptr2('parent'); // Grrr! What happened!?!? // apparently the call change_ptr2('A') screws something up. ?> </pre> <? // ex: ai et sw=2 ts=2 ?> ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=17959&edit=1

« previous php.bugs (#14100) next »