Преобразование не вложенного и скобочного массива в вложенный массив

Я нахожусь в PHP, и у меня есть массив, который выглядит так. Единый массив измерений, ключи которого заключены в скобки.

array( 'matrix[min_rows]' => '0', 'matrix[max_rows]' => '', 'matrix[col_order][]' => 'col_new_1', 'matrix[cols][col_new_0][type]' => 'text', 'matrix[cols][col_new_1][type]' => 'text', 'matrix[cols][col_new_0][label]' => 'Cell 1', 'matrix[cols][col_new_1][label]' => 'Cell 2', 'matrix[cols][col_new_0][name]' => 'cell_1', 'matrix[cols][col_new_1][name]' => 'cell_2', 'matrix[cols][col_new_0][instructions]' => '', 'matrix[cols][col_new_1][instructions]' => '', 'matrix[cols][col_new_0][width]' => '33%', 'matrix[cols][col_new_1][width]' => '', 'matrix[cols][col_new_0][settings][maxl]' => '', 'matrix[cols][col_new_0][settings][fmt]' => 'none', 'matrix[cols][col_new_0][settings][content]' => 'all', 'matrix[cols][col_new_1][settings][maxl]' => '140', 'matrix[cols][col_new_1][settings][multiline]' => 'y', 'matrix[cols][col_new_1][settings][fmt]' => 'none', 'matrix[cols][col_new_1][settings][content]' => 'all', ) 

Есть ли простой способ преобразовать это в обычный вложенный массив, то есть:

 array( 'matrix' => array( 'min_rows' => '0', 'max_rows' => '', 'col_order' => array('col_new_1'), 'cols' => array( 'col_new_0' => array( 'type' => 'text', 'label' => 'Cell 1', ....etc.... 

Это мое текущее решение, но мне было интересно, есть ли что-то более родное или эффективное:

 foreach ($decoded_field_type_settings as $key => $value) { if (preg_match_all('/\[(.*?)\]/', $key, $matches)) { $new_key = substr($key, 0, strpos($key, '[')); if ( ! isset($field_type_settings[$new_key])) { $field_type_settings[$new_key] = array(); } $array =& $field_type_settings[$new_key]; $count = count($matches[1]) - 1; foreach ($matches[1] as $i => $sub_key) { if ( ! $sub_key) { if ($i < $count) { $array[] = array(); } else { $array[] = $value; } } else { if ( ! isset($array[$sub_key])) { if ($i < $count) { $array[$sub_key] = array(); } else { $array[$sub_key] = $value; } } } if ($i < $count) { $array =& $array[$sub_key]; } } } else { $field_type_settings[$key] = $value; } } 

ОБНОВЛЕНИЕ: Я разместил ответ ниже.

Solutions Collecting From Web of "Преобразование не вложенного и скобочного массива в вложенный массив"

Это может сработать, хотя это может вызвать некоторые предупреждения:

 $matrix = array(); foreach($arr as $key => $value) { eval('$' . $key . ' = \'' . $value . '\';'); } var_dump($matrix); 

Я думаю, это должно сделать это …

 <?php function convert2dTo3d($source) { $refs = array(); $output = array(); foreach ($source AS $key => $val) { $tok = strtok($key, '[]'); $prev_tok = NULL; while ($tok !== FALSE) { $this_ref =& $refs[$tok]; if ($prev_tok === NULL) $output[$tok] =& $this_ref; else $refs[$prev_tok][$tok] =& $this_ref; $prev_tok = $tok; $tok = strtok('[]'); if ($tok === FALSE) $refs[$prev_tok] = $val; } } return $output; } // Test $source = array( 'matrix[min_rows]' => '0', 'matrix[max_rows]' => '', 'matrix[col_order][]' => 'col_new_1', 'matrix[cols][col_new_0][type]' => 'text', 'matrix[cols][col_new_1][type]' => 'text', 'matrix[cols][col_new_0][label]' => 'Cell 1', 'matrix[cols][col_new_1][label]' => 'Cell 2', 'matrix[cols][col_new_0][name]' => 'cell_1', 'matrix[cols][col_new_1][name]' => 'cell_2', 'matrix[cols][col_new_0][instructions]' => '', 'matrix[cols][col_new_1][instructions]' => '', 'matrix[cols][col_new_0][width]' => '33%', 'matrix[cols][col_new_1][width]' => '', 'matrix[cols][col_new_0][settings][maxl]' => '', 'matrix[cols][col_new_0][settings][fmt]' => 'none', 'matrix[cols][col_new_0][settings][content]' => 'all', 'matrix[cols][col_new_1][settings][maxl]' => '140', 'matrix[cols][col_new_1][settings][multiline]' => 'y', 'matrix[cols][col_new_1][settings][fmt]' => 'none', 'matrix[cols][col_new_1][settings][content]' => 'all', ); echo "<pre>"; print_r(convert2dTo3d($source)); echo "</pre>"; 

Кажется, что OP хочет в качестве вывода объявление массива, которое может быть проанализировано непосредственно PHP . Поэтому я предлагаю использовать var_export() .

 $array = array( 'matrix[min_rows]' => '0', // ...... // ...... // ...... 'matrix[cols][col_new_1][settings][content]' => 'all' ); $matrix = array(); foreach ($array as $key => $value) { // fix missing quotes around array indexes $key = str_replace(array("[", "]", "['']"), array("['", "']", "[]"), $key); // fill PHP array eval('$'.$key.' = $value;'); } var_export($matrix); 

Вы можете использовать простой парсер, основанный на регулярном выражении, который создает многомерный массив на основе информации, хранящейся в строке для каждого ключа:

 function parse_flat_matrix(array $flat) { $matrix = array(); $varname = 'matrix'; $nameToken = '[a-z0-9_]*'; foreach($flat as $key => $value) { $keys = preg_split(sprintf('/(\[%s\])/', $nameToken), $key, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); if ($varname !== array_shift($keys)) { throw new InvalidArgumentException(sprintf('Invalid key %s.', $key)); } $p =& $matrix; foreach($keys as $k) { $r = preg_match(sprintf('/^\[(%s)\]$/', $nameToken), $k, $kk); if (!$r) { throw new InvalidArgumentException(sprintf('Invalid subkey %s in key %s.', $k, $key)); } if ('' === $kk[1]) { $p =& $p[]; } else { $p =& $p[$kk[1]]; } } $p = $value; unset($p); } return $matrix; } с function parse_flat_matrix(array $flat) { $matrix = array(); $varname = 'matrix'; $nameToken = '[a-z0-9_]*'; foreach($flat as $key => $value) { $keys = preg_split(sprintf('/(\[%s\])/', $nameToken), $key, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); if ($varname !== array_shift($keys)) { throw new InvalidArgumentException(sprintf('Invalid key %s.', $key)); } $p =& $matrix; foreach($keys as $k) { $r = preg_match(sprintf('/^\[(%s)\]$/', $nameToken), $k, $kk); if (!$r) { throw new InvalidArgumentException(sprintf('Invalid subkey %s in key %s.', $k, $key)); } if ('' === $kk[1]) { $p =& $p[]; } else { $p =& $p[$kk[1]]; } } $p = $value; unset($p); } return $matrix; } 

С приведенными вами данными примера он создаст этот массив:

 Array ( [min_rows] => 0 [max_rows] => [col_order] => Array ( [0] => col_new_1 ) [cols] => Array ( [col_new_0] => Array ( [type] => text [label] => Cell 1 [name] => cell_1 [instructions] => [width] => 33% [settings] => Array ( [maxl] => [fmt] => none [content] => all ) ) [col_new_1] => Array ( [type] => text [label] => Cell 2 [name] => cell_2 [instructions] => [width] => [settings] => Array ( [maxl] => 140 [multiline] => y [fmt] => none [content] => all ) ) ) ) 

Это было самое простое решение, не связанное с регулярным анализом регулярных выражений:

 $original_array = array( 'matrix[min_rows]' => '0', 'matrix[max_rows]' => '', 'matrix[col_order][]' => 'col_new_1', 'matrix[cols][col_new_0][type]' => 'text', 'matrix[cols][col_new_1][type]' => 'text', 'matrix[cols][col_new_0][label]' => 'Cell 1', 'matrix[cols][col_new_1][label]' => 'Cell 2', 'matrix[cols][col_new_0][name]' => 'cell_1', 'matrix[cols][col_new_1][name]' => 'cell_2', 'matrix[cols][col_new_0][instructions]' => '', 'matrix[cols][col_new_1][instructions]' => '', 'matrix[cols][col_new_0][width]' => '33%', 'matrix[cols][col_new_1][width]' => '', 'matrix[cols][col_new_0][settings][maxl]' => '', 'matrix[cols][col_new_0][settings][fmt]' => 'none', 'matrix[cols][col_new_0][settings][content]' => 'all', 'matrix[cols][col_new_1][settings][maxl]' => '140', 'matrix[cols][col_new_1][settings][multiline]' => 'y', 'matrix[cols][col_new_1][settings][fmt]' => 'none', 'matrix[cols][col_new_1][settings][content]' => 'all', ); $query_string = http_build_query($original_array); $final_array = array(); parse_str($query_string, $final_array); var_dump($final_array);