Search code examples
phpmultidimensional-arrayreference

PHP - How to modify deeply nested associative arrays?


I'm having troubles building a deeply nested associative array in PHP. From the questions/answers I've seen here and there, I gathered I should use references but I just can't figure out how to do so.

I am using PHP 5.3

I'm parsing a file that looks like JSON. It contains nested "sections" enclosed in curly braces and I want to build up a tree representation of the file using nested associative arrays.

I'm starting with a root section and a "current section" variables:

$rootSection = array();
$currentSection = $rootSection;
$sections = array();

When I enter a new section ('{'), this is what I do:

$currentSection[$newSectionName] = array();
array_push($sections, $currentSection);
$currentSection = $currentSection[$newSectionName];

I use the $sections variable to pop out of a section ('}') into its parent one:

$currentSection = array_pop($sections);

And finally, when I want to add a property to my section, I basically do:

$currentSection[$name] = $value;

I've removed all attempt to use references from the above code, as nothing has worked so far... I might as well say that I am used to Javascript, where references are the default...

But it's apparently not the case with PHP? I've dumped my variables in my parsing code and I could see that all properties were correctly added to the same array, but the rootSection array or the one pushed inside $sections would not be updated identically.

I've been looking for a way to do this for a few hours now and I really don't get it... So please share any help/pointers you might have for me!

UPDATE: The solution

Thanks to chrislondon I tried using =& again, and managed to make it work.

Init code:

$rootSection = array();
$currentSection =& $rootSection;
$sections = array();

New section ('{'):

$currentSection[$newSectionName] = array();
$sections[] =& $currentSection;
$currentSection =& $currentSection[$newSectionName];

Exiting a section ('}'):

$currentSection =& $sections[count($sections) - 1];
array_pop($sections);

Note that starting around PHP 5.3, doing something like array_push($a, &$b); is deprecated and triggers a warning. $b =& array_pop($a) is also not allowed; that's why I'm using the []=/[] operators to push/"pop" in my $sections array.

What I initially had problems with was actually this push/pop to my sections stack, I couldn't maintain a reference to the array and was constantly getting a copy.

Thanks for your help :)


Solution

  • If you want to pass something by reference use =& like this:

    $rootSection = array();
    $currentSection =& $rootSection;
    
    $currentSection['foo'] = 'bar';
    
    print_r($rootSection);
    // Outputs: Array ( [foo] => bar )
    

    I've also seen the syntax like this $currentSection = &$rootSection; but they're functionally the same.