将非嵌套括号括起来的数组转换为嵌套数组

问题描述:

我正在使用PHP,并且有一个看起来像这样的数组。

I'm in PHP and I've got an array that looks like this. A single dimension array whose keys are bracketed strings.

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',
)

有没有简单的方法可以将其转换为普通嵌套数组,即:

Is there any easy way to convert that to a normal nested array, ie:

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....

这是我当前的解决方案,但我想知道是否还有其他更本机或更有效的方法:

This is my current solution, but I was wondering if there's something more native or efficient:

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;
    }
}

更新:我在下面发布了答案。

UPDATE: I posted an answer below.

这是最简单的解决方案,不涉及正则表达式解析:

This was the simplest solution, involving no regex parsing:

$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);