thenelson
asked on
foreach($_POST as $key => $value) not getting every $key
Reference (additional problem found to this question): https://www.experts-exchange.com/questions/28295433/Safari-posting-url-code.html
I have a form which has several fields with the same name. It is posting the following data:
"...Diagnoses=HA&Diagnoses =Migraine& Diagnoses= TBI&Diagno ses=TMJ... "
I am using the following code in the php script which only appends the last Diagnoses field ("TMJ") to the string $postData:
I would like to continue using fields with the same name because I would like to append those fields together on one line like this:
I am thinking of renaming the duplicate fields to:
Diagnosis01
Diagnosis02
Diagnosis03
etc
and then use substr ($key, 0, -2) to compare with the $peviousKey and append the "duplicate" $keys together.
Any other ideas on how to handle this.? TIA
I have a form which has several fields with the same name. It is posting the following data:
"...Diagnoses=HA&Diagnoses
I am using the following code in the php script which only appends the last Diagnoses field ("TMJ") to the string $postData:
foreach($_POST as $key => $value) {
$postData .= $key.'='.$value."\r\n";
}
I would like to continue using fields with the same name because I would like to append those fields together on one line like this:
foreach($_POST as $key => $value)
{
If ($key == $peviousKey)
{
echo "we are here<br>";
$postData .= ", ".$value;
}
else
{
$postData .= "\r\n".$key.'='.$value;
}
$peviousKey = $key;
}
var_dump($_POST); displays only the last Diagnosis field ("TMJ") in the array.I am thinking of renaming the duplicate fields to:
Diagnosis01
Diagnosis02
Diagnosis03
etc
and then use substr ($key, 0, -2) to compare with the $peviousKey and append the "duplicate" $keys together.
Any other ideas on how to handle this.? TIA
As a follow on, if you want all the diagnoses in one string, then use the PHP implode function:
$diagnoses = implode(",", $_POST['diagnoses']);
That will give you string with each of the diagnoses, separated by a comma.
ASKER
Chris,
Thanks for your response.
So as in your example, I could use name="diagnoses[]" for each field. I wouldn't need to use:
name="diagnoses[0]"; name="diagnoses[1]"; etc?
Would foreach($_POST as $key => $value) pick up each item in the subarray or would I have to include foreach ($_POST['diagnoses'] as $diag) also?
Using your suggestion, how would I build a string like this:
...
PreviousField=some text
Diagnoses=HA, Migraine, TMJ
PostField=some other text
...
I am thinking of renaming the duplicate fields to: "Diagnoses01,"; "Diagnoses02,"; etc. where the comma (or colon, semicolon, period, etc) at the end communicates the separator to use and then use this code to build my output:
Thanks for your response.
So as in your example, I could use name="diagnoses[]" for each field. I wouldn't need to use:
name="diagnoses[0]"; name="diagnoses[1]"; etc?
Would foreach($_POST as $key => $value) pick up each item in the subarray or would I have to include foreach ($_POST['diagnoses'] as $diag) also?
Using your suggestion, how would I build a string like this:
...
PreviousField=some text
Diagnoses=HA, Migraine, TMJ
PostField=some other text
...
I am thinking of renaming the duplicate fields to: "Diagnoses01,"; "Diagnoses02,"; etc. where the comma (or colon, semicolon, period, etc) at the end communicates the separator to use and then use this code to build my output:
foreach($_POST as $key => $value)
{
If (substr ($key, 0, -3) == $peviousKey)
{
$postData .= substr ($key, 0, -1).$value;
}
else
{
$postData .= "\r\n".$key.'='.$value;
}
$peviousKey = substr ($key, 0, -3);
}
//remove first "\r\n"
$postData = substr ($postData,2);
Do you see a problem with this?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>There's absolutely no reason to rename your fields
I am going to have to rename the Diagnoses fields to Diagnoses[]. Yes?
The code you suggested will work with multiple subarrays? It will keep the different subarrays separate? For example:
I like your solution better than mine but out of curiosity, what problems could I expect later on. I realize I would need to be careful to avoid field names that are the same except the last three characters but anything other than that?
I didn't know that php had an alternate if:-endif; foreach:-endforeach; syntax as opposed to using curly braces. Good to know.
I am going to have to rename the Diagnoses fields to Diagnoses[]. Yes?
The code you suggested will work with multiple subarrays? It will keep the different subarrays separate? For example:
<input type="text" name="diagnoses[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
<input type="text" name="symptom[]" />
<input type="text" name="surgery[]" />
<input type="text" name="surgery[]" />
>There's absolutely no reason to rename your fields - this will create problems later on.I like your solution better than mine but out of curiosity, what problems could I expect later on. I realize I would need to be careful to avoid field names that are the same except the last three characters but anything other than that?
I didn't know that php had an alternate if:-endif; foreach:-endforeach; syntax as opposed to using curly braces. Good to know.
OK. You're not renaming your fields - your just turning them into arrays by adding the square brackets - they'll still be called diagnoses, but instead of being a single value, it will be passed as an array.
In the sample HTML you've provided, your POST array will contains 3 keys - diagnoses, symptom, surgery and each of these keys will be an array containing the values.
When I say it will cause problems later on, there are a couple of things to bear in mind. The more complicated the code, the more likely there is for a typo. In your first post you mentioned calling your fields Diagnoses01, Diagnoses02 etc, and then in the post above you mention about the last 3 characters being the same - I'm guessing you meant the last 2 characters, but already inconsistency is creeping in.
The code you've posted assumes that all the diagnosis fields will be kept together, so you are relying on the $previousKey value to group them. What if you need to re-design your form and you need something like:
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
Your code won't work.
There are plenty of other examples of why you shouldn't do it your way, but it comes down to this: it's just not considered best-practice!
As for the alternative PHP control blocks - I find it easier to use these when you have lots of nested blocks - if statements inside of while loops inside of foreach loops etc - it's very easy to lose track of the brackets and your code ends up with 7 closing brackets and no indication of what they're closing!!
In the sample HTML you've provided, your POST array will contains 3 keys - diagnoses, symptom, surgery and each of these keys will be an array containing the values.
When I say it will cause problems later on, there are a couple of things to bear in mind. The more complicated the code, the more likely there is for a typo. In your first post you mentioned calling your fields Diagnoses01, Diagnoses02 etc, and then in the post above you mention about the last 3 characters being the same - I'm guessing you meant the last 2 characters, but already inconsistency is creeping in.
The code you've posted assumes that all the diagnosis fields will be kept together, so you are relying on the $previousKey value to group them. What if you need to re-design your form and you need something like:
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
<input type="text" name="diagnoses[]" />
<input type="text" name="symptom[]" />
Your code won't work.
There are plenty of other examples of why you shouldn't do it your way, but it comes down to this: it's just not considered best-practice!
As for the alternative PHP control blocks - I find it easier to use these when you have lots of nested blocks - if statements inside of while loops inside of foreach loops etc - it's very easy to lose track of the brackets and your code ends up with 7 closing brackets and no indication of what they're closing!!
ChrisStanyon has given you excellent advice here.
I would just like to add a security note. Never iterate over the $_POST array (or any external data, for that matter). Your script should know what elements are expected in the request and should only process those elements. This is a security issue that goes to the heart of "accept only known good values." Since the $_POST array is created by PHP from external data, it is by definition tainted. Therefore you cannot know that it contains good or bad values until you filter the external data. An example of why this matters is in AntiPHPractice Number 18.
See http://www.laprbass.com/RAY_temp_thenelson.php
I would just like to add a security note. Never iterate over the $_POST array (or any external data, for that matter). Your script should know what elements are expected in the request and should only process those elements. This is a security issue that goes to the heart of "accept only known good values." Since the $_POST array is created by PHP from external data, it is by definition tainted. Therefore you cannot know that it contains good or bad values until you filter the external data. An example of why this matters is in AntiPHPractice Number 18.
See http://www.laprbass.com/RAY_temp_thenelson.php
<?php // RAY_temp_thenelson.php
error_reporting(E_ALL);
// DEMONSTRATE HOW TO HANDLE EXTERNAL FORM DATA
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28305093.html
// THESE ARE THE ACCEPTABLE COLORS
$colors = array
( 'red'
, 'green'
, 'blue'
)
;
// IF THERE IS A POST-METHOD REQUEST TO SET THE COLOR
if (!empty($_POST['color']))
{
// CHECK THAT THE POST DATA MATCHES THE FORM DATA
if (in_array($_POST['color'], $colors))
{
// NORMALIZE / FILTER THE EXTERNAL DATA HERE
$color = strtolower($_POST['color']);
$color = ucFirst($color);
echo PHP_EOL . "THE COLOR IS $color";
}
else
{
trigger_error('SCRIPT UNDER ATTACK', E_USER_ERROR);
}
}
// CREATE THE RADIO BUTTONS FOR THE COLORS
$radios = NULL;
foreach ($colors as $rgb)
{
$radios .= '<input type="radio" name="color" value="' . $rgb . '" />' . "$rgb<br>";
}
// CREATE THE FORM USING HEREDOC SYNTAX
$form = <<<FORM
<form method="post">
$radios
<input type="submit" />
</form>
FORM;
echo $form;
Best regards, ~Ray
ASKER
That works great! Thanks!! I learned quite a few things.
ASKER
Ray,
Thanks for your input. I can see what you are saying: that anyone can post data to my php script and this could be dangerous. I can see how important this would be if the script acts on the data. In this case, the only thing I am doing is building a string and writing that to a text file which I then view. So I don't think anything bad would happen if someone sent me bogus data other than I would see garbage and not use it.
Do you agree?
Thanks for your input. I can see what you are saying: that anyone can post data to my php script and this could be dangerous. I can see how important this would be if the script acts on the data. In this case, the only thing I am doing is building a string and writing that to a text file which I then view. So I don't think anything bad would happen if someone sent me bogus data other than I would see garbage and not use it.
Do you agree?
Do you agree?Let me put it this way: http://xkcd.com/292/
ASKER
A followup:
Is there an easy way to not include empty array elements using
I am getting:
1986, fusion, , , , , 1996, esi, , , , .
I would like to eliminate the multiple commas.
Is there an easy way to not include empty array elements using
if (is_array($value)):
$postData .= $key.'='.implode(', ', $value).".\r\n";
I am getting:
1986, fusion, , , , , 1996, esi, , , , .
I would like to eliminate the multiple commas.
Sure, just replace contiguous commas with single commas. Something like this. You'll have to experiment with it some to get the regular expression exact for your work.
<?php
$rgx = '#,,+#';
$dat = '1986, fusion,,,,,1996,esi,,,';
echo preg_replace($rgx, ',', $dat);
Sure - just run $value through array_filter();
if (is_array($value)):
$value = array_filter($value);
$postData .= $key . '=' . implode(', ', $value) . PHP_EOL;
You might also want to use the PHP_EOL constant instead of the \r\n - again, good practice :)
ASKER
yep, that's what I did.
Thanks again
Thanks again
ASKER
What I tried first was similar to Ray's suggestion. I used str_replace to remove the multiple commas. That worked.
Chris' suggestion works too and i believe is more elegant.
Thanks again.
Chris' suggestion works too and i believe is more elegant.
Thanks again.
Open in new window
Then your POST array will contain a key of diagnoses, that is an array:Open in new window