I have read quite a few posts on this, most provide various solutions but none are really addressing the underlying "why"? I can't figure out PHPs behavior when processing a single $_POST array. Thus, this question hasn't been answered elsewhere (sufficiently).
In my form I have a single hidden input field (not multiple or looped):
<input type='hidden' id="nameIDs" name="nameIDs[]" value="">
And in in my JS I have:
var newIDs = [] ;
...
...
newIDs.push(thisID) ;
...
...
document.getElementById('nameIDs').value = newIDs
When the form is submitted I can see three values in the payload:
nameIDs[] : 1106,1135,2110
When PHP gets the info:
$nameIDs = $_POST['nameIDs'] ;
echo count($nameIDs)
// outputs "1"
// but the count should be 3
Ok, so thinking PHP is seeing the entire nameIDs as a string with commas I do:
$nameIDs = explode(",",$_POST['nameIDs']) ;
echo count($nameIDs) ;
// but this errors out on the `explode` saying that argument #2
// must be a string, but an array was given
Ok, so whats up...is this thing a string or an array? If I do:
$nameIDs = $_POST['nameIDs'] ;
echo $nameIDs ;
// It prints out the warning "Array"
// with no actual values.
So it appears it does think its an array, but only with one value, so next I try:
$nameIDs = $_POST['nameIDs'] ;
foreach ($nameIDs as $id) {
echo "This id is: $id" ;
}
// it prints out just '1106', but not the other two values
So...PHP is seeing an array with only 1 value in it...what happened to the other two values that I can clearly see are being passed to it? What am I missing here?
AFAICT you are trying to use a Javascript array of numbers (newIDs
) to set a single HTML input value. But an input value is always going to be a string. PHP does some magic to convert multiple inputs with the same name[]
into an array on the back end, but on the front end, each of those individual inputs is just a string value. In your case, AFAICT, you have a single input, and its value is going to be a string.
So you have 2 choices:
create multiple inputs, each with name="nameIDs[]"
, and have your JS populate the value attribute of each individually to a single value like 1106
. Make sure each input has a unique ID, if you're going to use IDs to address them in JS. Then on the back end $_POST['nameIDs']
will be an array of the individual values.
OR have a single input, with a name like name="nameIDs"
, and have your JS populate the value with a string describing all of your values together. How you represent it is up to you, and doesn't matter, as long as you can extract it on the back end. For eg if you go with comma-separated 1106,1135,2110
you can use explode()
on the back end.
As you say there are plenty of questions here about this already, but maybe none addressing this particular misconception.
As a side note, if you want to check what a variable looks like, use var_dump()
to see both the type and the value. I tried:
JS:
// Simulating your code
var newIDs = [] ;
[1106,1135,2110].forEach(thisID => {
newIDs.push(thisID) ;
});
// Note the code in your question has a typo here, missing the closing "'",
// I am assuming that's just a typo in the question, not in your real code.
document.getElementById('nameIDs').value = newIDs;
PHP:
<form method="post">
<input type='hidden' id="nameIDs" name="nameIDs[]" value="">
<input type='submit' value='Submit'>
</form>
<pre>
<?php var_dump($_POST); ?>
</pre>
And after submitting the form I see:
array(1) {
["nameIDs"]=>
array(1) {
[0]=>
string(14) "1106,1135,2110"
}
}
So setting your single input value to a Javascript array has actually created a nested array on the back end, and $_POST['nameIDs'][0]
is a string of your actual values, 1106,1135,2110
.