String to variable-depth multidimensional array
I'm trying to create a multidimensional array from a string (received from $_GET, input is validated, but not in this example). Each '-' will indicate a level in the multidimensional array.
Values can look like this (any form really, as long as '-' is present between keys). The array of values can map to any depth in the multidimensional array.
$array = array(
  'page-title' => 'Title of a page',
  'page-url' => 'http://www.mypage.com',
  'meta-page-author' => 'Some guy',
  'meta-page-created' => 'some timestamp'
);
I've tried different solutions, but the only thing working until now is the inital loop and extract of keys.
foreach ($array as $key =&开发者_开发知识库gt; $value) {
  if (strpos($key, '-') !== false) {
    $keyArray = explode('-', $key);
    // ??
  }
}
The output I'm hoping for, should look like this:
array(
  'page' => array(
      'title' => 'Title of a page',
      'url' => 'http://www.mypage.com'
  ),
  'meta' => array(
      'page' => array(
         'author' => 'Some guy',
         'created' => 'some timestamp'
       )
  )
);
Something like this should work:
<?php
$array = array(
  'page-title' => 'Title of a page',
  'page-url' => 'http://www.mypage.com',
  'meta-page-author' => 'Some guy',
  'meta-page-created' => 'some timestamp'
);
$result = array();
foreach ($array as $key => $value) {
    $keys = strpos($key, '-') !== false ? explode('-', $key) : array($key);
    $ptr = &$result;
    foreach ($keys as $k) {
        if (!isset($ptr[$k])) {
            $ptr[$k] = array();
        }
        $ptr = &$ptr[$k];
    }
    if (empty($ptr)) {
        $ptr = $value;
    } else {
        $ptr[] = $value;
    }
}
print_r($result);
What I did was explode your keys just like you were doing. I then looped through them creating a new array if the array didn't already exist. Using a reference I save the current point I was at in the array. Then once I had hit the last key I assigned the value. Hope this helps.
EDIT: Based on cHao's recommendation I changed
$keys = strpos($key, '-') !== false ? explode('-', $key) : $key;
to
$keys = strpos($key, '-') !== false ? explode('-', $key) : array($key);
to prevent failure on the foreach.
EDIT 2: I changed
$ptr = $value;
to
if (empty($ptr)) {
    $ptr = $value;
} else {
    $ptr[] = $value;
}
to handle cases like:
$array = array(
  'page-title' => 'Title of a page',
  'page-url' => 'http://www.mypage.com',
  'meta-page-author' => 'Some guy',
  'meta-page-created' => 'some timestamp',
  'page' => 'foo'
);
Just so you're aware, PHP can be made to accept whole big arrays like that. If you name the form elements like 'somename[page][title]', then when the form returns, you should see them already arranged as an array in $_GET.
In case you have your heart set on the current naming scheme, though...
$result = array();
foreach ($array as $key => $value) {
    $current =& $result;
    if (strpos($key, '-') !== false) {
        $keyArray = explode('-', $key);
        $bottomKey = array_pop($keyArray);
        foreach ($keyArray as $subKey) {
            if (!isset($current[$subKey]))
                $current[$subKey] = array();
            $current =& $current[$subKey];
        }
    } else {
        $bottomKey = $key;
    }
    $current[$bottomKey] = $value;
}
<?php
$array = array(
  'page-title' => 'Title of a page',
  'page-url' => 'http://www.mypage.com',
  'meta-page-author' => 'Some guy',
  'meta-page-created' => 'some timestamp'
);
$result = array();
foreach ($array as $key => $value) {
    if (strpos($key, '-') !== false) {
        $ak = "result['" . str_replace('-', '\'][\'', $key) . "'] = \"".$value."\"";
        eval('$'.$ak.';');
    }
}
var_dump($result);
?>
hope that helps
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论