1

I'm using PHP's array auto-index to structure my form data. Like:

<input name="users[][name]">
<input name="users[][name]">
<input name="users[][name]">

When I post this data PHP will automatically create an array for users under $_POST. But what if we need to add another field to each user, like:

<li>
  <input name="users[][name]">
  <input name="users[][nickname]">
</li>
<li>
  <input name="users[][name]">
  <input name="users[][nickname]">
</li>
<li>
  <input name="users[][name]">
  <input name="users[][nickname]">
</li>

Of course, the code above will create 6 entries instead of the desired 3 user entries.

Is there any way to access users[] (the last added entry) without increment it?

NikiC
  • 100,734
  • 37
  • 191
  • 225
cvsguimaraes
  • 12,910
  • 9
  • 49
  • 73
  • Use a counter variable? – nice ass Mar 20 '14 at 18:11
  • Your question is not that clear to me – Fabio Mar 20 '14 at 18:20
  • In this case you might be able to not use a counter variable – but once form elements like f.e. checkboxes become involved, the approach in larsAnders’ answer will fail you quite badly. And I also don’t particularly like about it, that it rips data apart that _logically_ belongs together. If you were just to provide the numerical index, you could loop over “users”, and have the attributes name, nickname etc. for that specific user right there. With his approach, you’ll have to loop over one of the name or nickname sub-arrays … and _hope_ the other ones have the same number of entries. – CBroe Mar 24 '14 at 09:08
  • @CBroe Thanks, I'm already considering it. About checkboxes, we can make not selected elements to be 'sent' by [grouping them with hidden inputs](http://stackoverflow.com/a/1992745/741981). – cvsguimaraes Mar 24 '14 at 09:15
  • Well if that seems “cleaner” to you then just supplying an index in the first place … – CBroe Mar 24 '14 at 09:19
  • @CBroe Haha, I'll not bother you with my context but, you know, sometimes weird stuff fit well on our weird context. – cvsguimaraes Mar 24 '14 at 09:23
  • What works for you works for you, so no objection to that from my side. My hint was more a general one – that it always depends on the specifics of the situation is something we can all agree on, I think. – CBroe Mar 24 '14 at 09:31

1 Answers1

2

On the HTML side, the only way to do precisely what you're asking is to use a counter variable and insert it dynamically into the HTML using a PHP loop or a JS function.

If that's not an option, here's another approach. Invert your brackets, so that the resulting arrays have a common index. In this case, the first two inputs generate $_POST[users][name][0] and $_POST[users][nickname][0]. Then, use the common index to reorganize the array in PHP. This solution will scale if you need to add new inputs.

HTML

<li>
  <input name="users[name][]">
  <input name="users[nickname][]">
</li>
<li>
  <input name="users[name][]">
  <input name="users[nickname][]">
</li>
<li>
  <input name="users[name][]">
  <input name="users[nickname][]">
</li>

PHP

<?php

$inputs = $_POST;
$result = array();

//Using a column-row analogy
foreach ($inputs as $columnName => $columnValues)
{
    foreach ($columnValues as $rowIndex => $columnValue)
    {
        $result[$rowIndex][$columnName] = $columnValue;
    }
}

print_r($result);

?>

Just a side note

It's possible to group values while using auto-indexed arrays. But it's such a dark sorcery:

$users = array();

// ...
// wild stuff happening up there

//This will NOT get the last instantiated element
//actually it will append a new element and return the pointer to it (wtf?)
$newUser =& $users[]; 
$newUser['name'] = 'voodo';
$newUser['nickname'] = 'jacu';

See how it 'works'.

Community
  • 1
  • 1
larsAnders
  • 3,813
  • 1
  • 15
  • 19