2017-02-19 82 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" 
         ) 
       ) 
     ) 
)