2017-02-19 73 views
0

我有一个这样的字符串:鸿沟字符串assoc命令阵列

$config = 'app.name = "My App"; 
      app.id = "myappid"; 
      app.components.cache.id = "Memcache";'; 

我需要将其转换成数组是这样的:

app=>[ 
    'name=>'My App', 
    'id'=>'myappid', 
    'components'=>[ 
     'cache'=>['id'=>'Memcache'] 
    ] 
] 

我使用爆炸,对上个鸿沟,但我不知道接下来我需要做什么。

$arr = explode(";", $config); 
$data = []; 
foreach ($arr as $item) { 
    $pieces = explode('=', $item); 
    $pieces_dotes = explode('.', $pieces[0]); 
    foreach ($pieces_dotes as $piece) { 
    //what i need to do here? 
    } 
} 

回答

0

这个怎么样?在内部foreach循环中,您将通过引用自身来分配临时变量,因此您会构建一堆数组键,然后在最后为其分配值。

$config = 'app.name = "My App"; 
      app.id = "myappid"; 
      app.components.cache.id = "Memcache";'; 
$arr = explode(";", $config); 
$data = []; 
foreach ($arr as $item) { 
    $temp = &$data; 
    $item = trim($item); 
    if (empty($item)) continue; 
    list($setting, $value) = explode("=", trim($item)); 
    $setting = explode(".", trim($setting)); 
    foreach ($setting as $set) { 
     $temp = &$temp[$set]; 
    } 
    $temp = trim($value, '" '); 
} 
print_r($data); 
0

这可以通过建立基于键的数组级别并保持对数组中最后添加的级别的引用来解决。我的解决方案(基于你已经有)如下:

<?php 

$config = 'app.name = "My App"; 
      app.id = "myappid"; 
      app.components.cache.id = "Memcache";'; 

$arr = explode(";", $config); 
$data = []; 

foreach ($arr as $item) { 
    $pieces = explode('=', $item); 
    $currentValue = trim(str_replace('"', '', $pieces[1])); 
    $pieces_dotes = explode('.', $pieces[0]); 

    // Set initial value of $currentLevel to root of data array 
    $currentLevel = &$data; 

    // Initiate count & iterator vars 
    $numPieces = count($pieces_dotes); 
    $i = 0; 
    foreach ($pieces_dotes as $piece) { 
     // Increment $i and set $newKey to be trimmed version of current piece of the dot notated level 
     $i++; 
     $newKey = trim($piece); 

     // Skip empty $newKey 
     if(empty($newKey)) { 
      continue; 
     } 

     // Assign the $currentValue once we are at the required depth 
     if($i == $numPieces) { 
      $currentLevel[$newKey] = $currentValue; 
     } 

     // We are not at the required depth yet so initiate the key as an array if required 
     if(empty($currentLevel[$newKey])) { 
      $currentLevel[$newKey] = []; 
     } 

     // Set the $currentLevel to reference the new key 
     if(is_array($currentLevel[$newKey])) { 
      $currentLevel = &$currentLevel[$newKey]; 
     } 
    } 
} 

希望这有助于!

0

使用自定义的递归函数fillBypath解决办法:

/** 
* Fills an array by hierarchical 'key path' 
* 
* @param type $value value in each 'key path' 
* @param type $keys hierarchical key list 
* @param type $arr the resulting array(passed by reference) 
*/ 
function fillByPath($value, $keys, &$arr) { 
    $c = count($keys) - 1; 

    foreach ($keys as $idx => $k) { 
     if ($idx == $c) {  // check if it's the last key in the "key path" 
      $arr[$k] = $value; 
      break; 
     } 

     if (isset($arr[$k]) && is_array($arr[$k])) { 
      fillByPath($value, array_slice($keys, $idx + 1), $arr[$k]); 
      break; 
     } else { 
      $arr[$k] = []; 
      fillByPath($value, array_slice($keys, $idx + 1), $arr[$k]); 
      break; 
     } 
    } 
} 

$config = 'app.name = "My App"; 
      app.id = "myappid"; 
      app.components.cache.id = "Memcache";'; 

$result = []; 
foreach (array_filter(explode(";", $config)) as $path) { 
    list($keyPath, $v) = explode(" = ", trim($path)); 
    $keys = explode(".", $keyPath); // getting key list 
    fillByPath($v, $keys, $result); 
} 

print_r($result); 

输出:

(
    [app] => Array 
     (
      [name] => "My App" 
      [id] => "myappid" 
      [components] => Array 
       (
        [cache] => Array 
         (
          [id] => "Memcache" 
         ) 
       ) 
     ) 
)