Wednesday, September 10, 2008

Beware of References

I got tripped up by the following code:
// This data actually comes from csv file
$data = array(
    array('Area1', null, null),
    array(null, 'Section1', null),
    array(null, null, 'Location1'),
    array('Area2', null, null),
    array(null, 'Section2', null),
    array(null, null, 'Location2')
);
$root = array();
foreach ($data as $row) {
    if ($row[0]) { // Is Area
        $area = array();
        $root[$row[0]] =& $area;
    } elseif ($row[1]) { // Is Section
        $section = array();
        $area[$row[1]] =& $section;
    } elseif ($row[2]) { // Is Location
        $section[] = $row[2];
    }
}
print_r($root); 
Expected result:
Array(
[Area1] => Array(                     
        [Section1] => Array(
                [0] => Location1
            )               
    )
[Area2] => Array(       
        [Section2] => Array(          
                [0] => Location2
            )               
    )
)
Actual result:
Array(
[Area1] => Array(                     
        [Section2] => Array(
                [0] => Location2
            )               
    )
[Area2] => Array(       
        [Section2] => Array(          
                [0] => Location2
            )               
    )
)
So what did I do wrong? To answer this lets look at a simpler example:
$a = array();
$b =& $a;
$a[] = 'hello';
echo implode(' ', $b); // Outputs 'hello'
$a = array('world');
echo implode(' ', $b); // Outputs 'world' 
See I was expecting the last line to output 'hello' because I was thinking references were like C pointers. That is:
void* a = array();
void* b = *a;
So looking up the PHP manual it says:
They are not like C pointers; instead, they are symbol table aliases... References can be thought of as hardlinking in Unix filesystem.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home