Converting a multi-dimensional array into HTML form fields - how?
I'm trying to take a multidimensional array and convert it into HTML form fields, like this:
<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="0开发者_Go百科8">
<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">
Here is what I have so far:
$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;
}
This works fine until ip_address, which results in:
<input type="hidden" name="c_record[contact][0][date_submitted][ip_address]" value="192.168.1.1">
And any additional fields after ip_address keep having the previous field names added to them.
How can I make this work?
You could manhandle http_build_query
into service for this purpose, since it naturally creates the scrunched-together keys you're looking for. If you wait until the end to urldecode
your keys and values, it's easy to explode the output, since any =
or &
in a key or value will be safely encoded.
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;
}
You are updating $prefix in the current scope before you pass it into the recursive function. You don't want to do that. For multi-valued arrays it means that in the next iteration of the current function the prefix is going to contain the name of the previoust array. You can work around this by passing an updated prefix to the recursive function independent of $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;
}
Try that.
As a hack and temporary solution, I did the following, although it's damn ugly and not flexible:
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');
}
}
}
}
}
}
}
}
}
}
}
}
精彩评论