将多维数组转换为HTML表单字段 - 如何?

时间:2011-02-09 08:12:17

标签: php html arrays

我正在尝试使用多维数组并将其转换为HTML表单字段,如下所示:

<input type="hidden" name="c_record[contact][0][name]" value="First Last">
<input type="hidden" name="c_record[contact][0][date_submitted][date]" value="2010-01-01">
<input type="hidden" name="c_record[contact][0][date_submitted][hour]" value="10">
<input type="hidden" name="c_record[contact][0][date_submitted][min]" value="08">
<input type="hidden" name="c_record[contact][0][date_submitted][sec]" value="16">
<input type="hidden" name="c_record[contact][0][ip_address]" value="192.168.1.1">

这是我到目前为止所做的:

$fields = array(
    'c_record' => array(
        'contact' => array(
            0 => array(
                'name' => 'First Last',
                'date_submitted' => array(
                    'date' => '2010-01-01',
                    'hour' => '10',
                    'min' => '08',
                    'sec' => '16',
                ),
                'ip_address' => '192.168.1.1',
            ),
        ),
    ),
);
$form_html = array_to_fields($fields);

function array_to_fields($fields, $prefix = '') {
    $form_html = '';

    foreach ($fields as $name => $value) {
        if ( ! is_array($value)) {
            if ( ! empty($prefix)) {
                $name = $prefix . '[' . $name . ']';
            }
            // generate the hidden field
            $form_html .= Form::hidden($name, $value) . EOL;
        } else {
            if ( ! empty($prefix)) {
                $prefix .= '[' . $name . ']';
            } else {
                $prefix = $name;
            }
            $form_html .= array_to_fields($value, $prefix);
        }
    }

    return $form_html;
}

直到ip_address才能正常工作,结果是:

<input type="hidden" name="c_record[contact][0][date_submitted][ip_address]" value="192.168.1.1">

ip_address之后的任何其他字段都会添加先前的字段名称。

我该如何做到这一点?

3 个答案:

答案 0 :(得分:4)

您可以为此目的对http_build_query进行操作,因为它会自然地创建您正在寻找的拼凑密钥。如果您等到urldecode键和值的结尾,则很容易爆炸输出,因为键或值中的任何=&都将被安全编码。

function array_to_fields($array) {
    $html = '';

    $entries = explode('&', http_build_query($array));
    foreach ($entries as $entry) {
        list($key, $value) = explode('=', $entry);
        $html .= Form::hidden(urldecode($key), urldecode($value)) . EOL;
    }

    return $html;
}

答案 1 :(得分:1)

在将其传递到递归函数之前,您正在更新当前作用域中的$ prefix。你不想那样做。对于多值数组,这意味着在当前函数的下一次迭代中,前缀将包含最前面的数组的名称。您可以通过将更新的前缀传递给独立于$ prefix的递归函数来解决此问题。

function array_to_fields($fields, $prefix = '') {
$form_html = '';

foreach ($fields as $name => $value) {
    if ( ! is_array($value)) {
        if ( ! empty($prefix)) {
            $name = $prefix . '[' . $name . ']';
        }
        // generate the hidden field
        $form_html .= Form::hidden($name, $value) . EOL;
    } else {
        if ( ! empty($prefix)) {
            $subprefix = $prefix . '[' . $name . ']';
        } else {
            $subprefix = $name;
        }
        $form_html .= array_to_fields($value, $subprefix);
    }
}

return $form_html;
}

试试。

答案 2 :(得分:0)

作为一个黑客和临时解决方案,我做了以下工作,虽然它太丑陋且不灵活:

    foreach ($fields as $name1 => $value1) {
        if ( ! is_array($value1)) {
            $form_html .= Form::hidden($name1, $value1) . EOL;
        } else {
            foreach ($value1 as $name2 => $value2) {
                if ( ! is_array($value2)) {
                    $form_html .= Form::hidden($name1 . '[' . $name2 . ']', $value2) . EOL;
                } else {
                    foreach ($value2 as $name3 => $value3) {
                        if ( ! is_array($value3)) {
                            $form_html .= Form::hidden($name1 . '[' . $name2 . '][' . $name3 . ']', $value3) . EOL;
                        } else {
                            foreach ($value3 as $name4 => $value4) {
                                if ( ! is_array($value4)) {
                                    $form_html .= Form::hidden($name1 . '[' . $name2 . '][' . $name3 . '][' . $name4 . ']', $value4) . EOL;
                                } else {
                                    foreach ($value4 as $name5 => $value5) {
                                        if ( ! is_array($value5)) {
                                            $form_html .= Form::hidden($name1 . '[' . $name2 . '][' . $name3 . '][' . $name4 . '][' . $name5 . ']', $value5) . EOL;
                                        } else {
                                            foreach ($value5 as $name6 => $value6) {
                                                if ( ! is_array($value6)) {
                                                    $form_html .= Form::hidden($name1 . '[' . $name2 . '][' . $name3 . '][' . $name4 . '][' . $name5 . '][' . $name6 . ']', $value6) . EOL;
                                                } else {
                                                    throw new Kohana_Exception('There are no levels than are supported by array_to_fields . Ending entire loop');
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }