69

I got a form like this

<form>
    <input type="text" class="form-control" placeholder="Titel" name="levels[level]">
    <input type="text" class="form-control" placeholder="Titel" name="levels[build_time]">

    <input type="text" class="form-control" placeholder="Titel" name="levels[level]">
    <input type="text" class="form-control" placeholder="Titel" name="levels[build_time]">
</form>

I'd like to have as $_POST output an array like:

Array (
  [1] => Array ( [level] => 1 [build_time] => 123 )
  [2] => Array ( [level] => 2 [build_time] => 456 )
)

I know I could do something like name="levels[1][build_time]" and so on, but since these elements get added dynamically, it would be hard to add an index. Is there another way?


As suggested, I changed my form. I also included my whole HTML now, because I think I'm missing something here. My HTML now:

<div class="form-group">
  <label class="col-md-2">Name(z.B. 1)</label>
  <div class="col-md-10">
    <input type="text" class="form-control" placeholder="Titel" name="levels[][level]">
  </div>

  <label class="col-md-2">Bauzeit(In Sekunden)</label>
  <div class="col-md-10">
    <input type="text" class="form-control" placeholder="Titel" name="levels[][build_time]">
  </div>
</div>

<div class="form-group">
  <label class="col-md-2">Name(z.B. 1)</label>
  <div class="col-md-10">
    <input type="text" class="form-control" placeholder="Titel" name="levels[][level]">
  </div>

  <label class="col-md-2">Bauzeit(In Sekunden)</label>
  <div class="col-md-10">
    <input type="text" class="form-control" placeholder="Titel" name="levels[][build_time]">
  </div>
</div>

The output I get now is:

[levels] => Array (
  [0] => Array ( [level] => 1 )
  [1] => Array ( [build_time] => 234 )
  [2] => Array ( [level] => 2 )
  [3] => Array ( [build_time] => 456 )
)

As suggested in your edit, I edited my form and moved the square brackets to the end of the name. The output I get now is:

[levels] => Array (
  [level] => Array (
    [0] => 1
    [1] => 2
  )
  [build_time] => Array (
    [0] => 234
    [1] => 456
  )
)

I guess that would kind of work, but it still looks complicated. Isn’t there a better way?

4 Answers 4

102

Simply add [] to those names like

 <input type="text" class="form-control" placeholder="Titel" name="levels[level][]">
 <input type="text" class="form-control" placeholder="Titel" name="levels[build_time][]">

Take that template and then you can add those even using a loop.

Then you can add those dynamically as much as you want, without having to provide an index. PHP will pick them up just like your expected scenario example.

Edit

Sorry I had braces in the wrong place, which would make every new value as a new array element. Use the updated code now and this will give you the following array structure

levels > level (Array)
levels > build_time (Array)

Same index on both sub arrays will give you your pair. For example

echo $levels["level"][5];
echo $levels["build_time"][5];
Sign up to request clarification or add additional context in comments.

4 Comments

Ooops sorry I had my Square brackets at the wrong place. Please move them to end of the name like my new edit.
I see you edited your post again :) I got the same structure now but it's still not what I originally wanted. That's the best way to do it?
That isn't complicated. You can access one pair like echo $levels["level"][5]; echo $levels["build_time"][5];
this is a pretty great feature of HTML, saves a lot of tampering around on server side. Thanks for your answer, it helped me alot
39

If it is OK for you to index the array, you can do this:

<form>
    <input type="text" class="form-control" placeholder="Titel" name="levels[0][level]">
    <input type="text" class="form-control" placeholder="Titel" name="levels[0][build_time]">

    <input type="text" class="form-control" placeholder="Titel" name="levels[1][level]">
    <input type="text" class="form-control" placeholder="Titel" name="levels[1][build_time]">

    <input type="text" class="form-control" placeholder="Titel" name="levels[2][level]">
    <input type="text" class="form-control" placeholder="Titel" name="levels[2][build_time]">
</form>

... to achieve this:

[levels] => Array (
  [0] => Array (
    [level] => 1
    [build_time] => 2
  )
  [1] => Array (
    [level] => 234
   [build_time] => 456
  )
  [2] => Array (
    [level] => 111
    [build_time] => 222
  )
)

But if you remove one pair of inputs (dynamically, I suppose) from the middle of the form then you'll get holes in your array, unless you update the input names...

1 Comment

I would prefer this style of inputs as it becomes easier to process this once posted. However, it's a bit complex when you dynamically add more rows of inputs to the form. Is there any easier solution to this?
20

HTML: Use names as

<input name="levels[level][]">
<input name="levels[build_time][]">

PHP:

$array = filter_input_array(INPUT_POST);
$newArray = array();
foreach (array_keys($array) as $fieldKey) {
    foreach ($array[$fieldKey] as $key=>$value) {
        $newArray[$key][$fieldKey] = $value;
    }
}  

$newArray will hold data as you want

Array ( 
  [0] => Array ( [level] => 1 [build_time] => 123 ) 
  [1] => Array ( [level] => 2 [build_time] => 456 )
)

1 Comment

I'm not sure why this was downvoted, but this was exactly what I needed.
8

In addition:

For those who have a empty $_POST variable, don't use this:

name="[levels][level][]"

Rather use this (as it is already here in this example):

name="levels[level][]"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.