Consider a PHP script which generates a form, which looks like a table and has the same recurring rows output many times:
print('<form method="POST" action="index.php">
<table>
<tr>
<th>Row #</th>
<th><tt>name</tt></th>
<th><tt>value</tt></th>
</tr>');
for ( $i = 1; $i <= 4; $i++ )
{
print('<tr>
<th>' .$i. '</th>
<td><input type="text" name="name_' .$i. '" size="20"></td>
<td><input type="text" name="value_' .$i. '" size="4"></td>
</tr>');
}
print('</table>
<input type="submit" name="is_submit" value="Submit">
</form>');
When you submit this form, the $_POST
array will look like this:
array (
'name_1',
'value_1',
'name_2',
'value_2',
'name_3',
'value_3',
'name_4',
'value_4',
'is_submit',
);
What I wish to do, it to organize this input so it will look something like this:
array (
1 =>
array (
'name',
'value',
),
2 =>
array (
'name',
'value',
),
3 =>
array (
'name',
'value',
),
4 =>
array (
'name',
'value',
),
);
It means, that every field ending in the same row ID number is grouped together with fellow fields (in the same row) in a two-level deep array.
I have been doodling around with options to solve this and came up with the following "solution" (the organized array (above) is actually a dump of the $output
created by this approach):
if ( array_key_exists('is_submit', $_POST) ) // Form is submitted properly
{
unset($_POST['is_submit']); // Drop the status key
foreach ( array_keys($_POST) as $key )
{
$key_exploded = explode("_", $key); // [0] is key 'basename', [1] is the 'row ID'
$output[ $key_exploded[1] ][ $key_exploded[0] ] = $_POST[$key];
}
}
The big problem is that this method looks a bit obfuscated and hard-coded. I think and hope that the more-advanced people around here could guide me for a more dynamical (that unset
row is itchy, that I need to call unset()
on every non-table row) and better method.
Change these lines:
<td><input type="text" name="name_' .$i. '" size="20"></td>
<td><input type="text" name="value_' .$i. '" size="4"></td>
to
<td><input type="text" name="foobar['.$i.'][name]" size="20"></td>
<td><input type="text" name="foobar['.$i.'][value]" size="4"></td>
$_POST['foobar'] now will have the desired structure.
You could introduce an additional condition in the foreach loop, if you don’t want to change your form:
if ( array_key_exists('is_submit', $_POST) ) // Form is submitted properly
{
foreach ( array_keys($_POST) as $key )
{
$key_exploded = explode("_", $key); // [0] is key 'basename', [1] is the 'row ID'
// check if keys start with 'name' or 'value'
if ($key_exploded[0] == 'name' || $key_exploded[0] == 'value')
$output[ $key_exploded[1] ][ $key_exploded[0] ] = $_POST[$key];
}
}