2016-10-04 53 views
2

有URL參數: -解析嵌套的數組了URL

/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai

正如你可以看到,有兩個類似數組的字符串。我想將它們轉換成數組
['addr' => ['nation' => ['key' => ['sx' => China]]], ['city' => 'Shanghai']]

我想: -

$results = []; 
$str = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai/'; 
$params = explode('/', $str); 
if($params[0] == '') unset($params[0]); 
while(key($params) !== null && current($params)) { 
    $key = current($params); 
    $value = next($params); 
    if(strpos($key, '[')) { 
     $sub_keys = explode('[', $key); 
     foreach($sub_keys as &$sub_key) { 
      $sub_key = trim($sub_key, ']'); 
     } 

     $count = count($sub_keys); 
     $ref = &$results; 
     foreach($sub_keys as $k => $v) { 
      if($k == $count - 1) { 
       $ref[$v] = $value; 
       $ref = &$ref[$v]; 
      } else { 
       $ref[$v] = $ref[$v] ?? []; 
       $ref = &$ref[$v]; 
      } 
     } 
    } else { 
     $results[$key] = $value; 
    } 
    next($params); 
} 
var_dump($results); 

它的工作原理。它得到:

array(3) { 
    ["name"]=> string(5) "Aario" 
    ["gender"]=> string(4) "male" 
    ["addr"]=> array(2) { 
     ["nation"]=> array(1) { 
      ["key"]=> array(1) { 
       ["sx"]=> string(5) "China" 
      } 
     } 
     ["city"]=> &string(8) "Shanghai"  // please notice here 
    } 
} 

但是我害怕參考文獻(&)會犯錯誤。

有沒有更好的方法來做到這一點?

+2

你需要改變你的鏈接結構,通過它您收到這類網址。更容易和正確的工作。 –

+0

這只是一種特殊的需要...... – AarioAi

回答

1

將其轉換爲查詢字符串應該導致短暫代碼:

$str = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai/'; 
$query = array_reduce(
    array_chunk(explode('/', trim($str, '/')), 2), 
    function ($string, $item) { 
     return $string . $item[0] . (isset($item[1]) ? '=' . $item[1] : '') . '&'; 
    } 
); 

parse_str($query, $result); 
0

一些簡單的正則表達式處理:

$replacements = [ 
    'addr' => [ 
     'nation' => [ 
      'key' => [ 
       'sx' => 'China' 
      ] 
     ], 
     'city' => 'Shanghai' 
    ] 
]; 

$url = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai'; 

$result = preg_replace_callback('~[^/]+~', function (array $match) use ($replacements) { 
    if (preg_match_all('/\w+/', $match[0], $keys) > 1) { 
     return array_reduce($keys[0], function ($a, $k) { return $a[$k]; }, $replacements); 
    } else { 
     return $match[0]; 
    } 
}, $url); 

var_dump($result); 
string(53) "/name/Aario/gender/male/China/China/Shanghai/Shanghai" 

請注意,我改變了你的$replacements數據,因爲它不符合在URL中的佔位符。

0

嘗試使用遞歸函數

$str = '/name/Aario/gender/male/addr[nation][key][sx]/China/addr[city]/Shanghai/'; 
$params = explode('/', $str); 
if($params[0] == '') unset($params[0]); 


$is_odd_pos = true; 
$results = []; 

function rec(&$array, $keys, $val){ 
    $keys = array_values($keys); 

    if(count($keys) > 1){ 
     $key = $keys[0]; 
     if(!isset($array[$key])) 
      $array[$key] = []; 

     rec($array[$key], array_slice($keys, 1), $val); 
     return; 
    } 

    $array[$keys[0]] = $val; 
} 

foreach($params as $k => $value) { 
    if($k % 2 == 0){ 
     $key = $params[$k - 1]; 
     preg_match_all('/\[(\w+)\]/', $key, $matches); 
     if(count($matches[1]) == 0){ 
      $results[$key] = $value; 
      continue; 
     } 
     $key = explode('[', $key, 2)[0]; 
     if(!isset($results[$key])) 
      $results[$key] = []; 

     rec($results[$key], $matches[1], $value); 
    } 
} 

var_dump($results);