How do I recursively create a multidimensional array?

I am trying to create a multidimensional array whose parts are defined by a string. I use it .

as a separator and each part (except the last) should be an array
for example:

config.debug.router.strictMode = true

      

I need the same results as for input:

$arr = array('config' => array('debug' => array('router' => array('strictMode' => true))));

      

This issue really got me going in circles, any help is appreciated. Thank!

+2


source to share


5 answers


Suppose we already have a key and a value in $key

and $val

, then you can do this:

$key = 'config.debug.router.strictMode';
$val = true;
$path = explode('.', $key);

      

Building the array from left to right:



$arr = array();
$tmp = &$arr;
foreach ($path as $segment) {
    $tmp[$segment] = array();
    $tmp = &$tmp[$segment];
}
$tmp = $val;

      

And from right to left:

$arr = array();
$tmp = $val;
while ($segment = array_pop($path)) {
    $tmp = array($segment => $tmp);
}
$arr = $tmp;

      

+4


source


I say I split everything, start at the value and work back from there, each time through, wrapping what you have in another array. For example:

$s = 'config.debug.router.strictMode = true';
list($parts, $value) = explode(' = ', $s);

$parts = explode('.', $parts);
while($parts) {
   $value = array(array_pop($parts) => $value);
}

print_r($parts);

      



Definitely rewrite it to have error checking.

+4


source


Gumbo's answer looks good.

However, it looks like you want to parse a typical .ini file.

Consider using library code instead of rewinding your own.

For example, Zend_Config does a great job with this.

+1


source


I really love that JasonWolf answers this.

As for possible mistakes: yes, but he gave a great idea, now the reader needs to make it bulletproof.

My need was a little simpler: from a delimited list, create an MD array. I modified his code slightly to give me exactly this. This version will give you an array with or without a definition string, or even a non-delimited string.

I hope someone can make it even better.

$parts = "config.debug.router.strictMode";

$parts = explode(".", $parts);

$value = null;

while($parts) {
  $value = array(array_pop($parts) => $value);
}


print_r($value);

      

+1


source


// The attribute to the right of the equals sign
$rightOfEquals = true; 

$leftOfEquals = "config.debug.router.strictMode";

// Array of identifiers
$identifiers = explode(".", $leftOfEquals);

// How many 'identifiers' we have
$numIdentifiers = count($identifiers);


// Iterate through each identifier backwards
// We do this backwards because we want the "innermost" array element
// to be defined first.
for ($i = ($numIdentifiers - 1); $i  >=0; $i--)
{

   // If we are looking at the "last" identifier, then we know what its
   // value is. It is the thing directly to the right of the equals sign.
   if ($i == ($numIdentifiers - 1)) 
   {   
      $a = array($identifiers[$i] => $rightOfEquals);
   }   
   // Otherwise, we recursively append our new attribute to the beginning of the array.
   else
   {   
      $a = array($identifiers[$i] => $a);
   }   

}

print_r($a);

      

0


source







All Articles