PHP Form woes
April 4, 2012 10:03 AM   Subscribe

LearningProgramming(PHP)Filter: I have a form with a select field (with about 70 options) and a couple of radio buttons. The final result differs according to what has been selected. I'm pretty sure the worst possible way to do this would be to use a lot of IF and IF ELSE statements but I'm not sure what would be the "correct" way to do it.

Bonus question: Are there any resources or books to learn this kind of thing? Sometimes I feel like I'm hammering a nail with a rock: it works but it's not pretty.
posted by Memo to Computers & Internet (13 answers total) 1 user marked this as a favorite
 
That's a pretty vague question. A select field and a couple of radio buttons is only going to give you a handful of $_POST variables when you submit the form.

What's in the select field? What do you want to do with it?
posted by le morte de bea arthur at 10:07 AM on April 4, 2012




If you really do have 70 different possibilities, I'd say use a switch statement: http://php.net/manual/en/control-structures.switch.php

In general, the php.net docs are a great resource! That's how I learned PHP.
posted by guybrush_threepwood at 10:15 AM on April 4, 2012 [2 favorites]


Response by poster:
le morte de bea arthur: "That's a pretty vague question. A select field and a couple of radio buttons is only going to give you a handful of $_POST variables when you submit the form.

What's in the select field? What do you want to do with it?
"
I know it's a vague question but I'm not sure how to explain it better.

The select field has countries, the radio buttons allow the user to specify if they are a male or a woman. Each country has three values. One for male, one for female and one if the radio button is not clicked.

What I meant by IF and IF ELSE is that I could easily do something like

if ($country == "United States") {
if ($radio == "male") { DO THIS }
else if
$radio == "female" { DO THIS }
else { DO THIS }
}


and repeat it for each and every country but I'm not sure if that's the "correct" way to do it.
posted by Memo at 10:18 AM on April 4, 2012


I think this will depend on what you plan to do with the data. Typically you'd take your two values (country and gender) and use those to produce a query on a database table or something.

Again, I don't think you're giving enough information.

You could certainly use a huge if-then-elseif-else structure, or a switch-case structure to go through every possible combination, but generally speaking you'd only want to do that if there was a different set of things you wanted to do for every combination.
posted by le morte de bea arthur at 10:30 AM on April 4, 2012


Well, you'd likely want to invert the test order, since there are fewer genders than countries, and maybe use switch instead of if/then on the inner case, but otherwise you're pretty much on the right track:

if ($radio == 'male') {
  switch ($country) {
    case 'United States': {foo}; break;
    case 'Canada': {bar}; break;
    ...
  }
} else if ($radio == 'female') {
  switch ($country) {
    ...
  }
}

(This assumes that the results you need to plug in really do differ for every combination of country and gender, and that there isn't a simpler programmatic way to construct those results. Which is more or less what le morte de bea arthur was asking: if you can be more specific about what happens in the "DO THIS" parts of your code, we might be able to suggest more concise or efficient ways of achieving it.)
posted by ook at 10:31 AM on April 4, 2012


Response by poster:
le morte de bea arthur: "I think this will depend on what you plan to do with the data. Typically you'd take your two values (country and gender) and use those to produce a query on a database table or something."
Oh, that's an idea.
le morte de bea arthur: "Again, I don't think you're giving enough information."

ook: " if you can be more specific about what happens in the "DO THIS" parts of your code, we might be able to suggest more concise or efficient ways of achieving it."
The DO THIS is just changing a variable's value.
So, male: $value=1, female: $value=2, nothing: $value=3. (Different values for each country of course).
posted by Memo at 10:36 AM on April 4, 2012


Best answer: There's nothing inherently wrong with your approach, but I'd make a lookup table that maps your country/gender choice to your codes.

Here's one such example as a multidimensional indexed array. (An array of objects would also work)
$lookupTable = array(
  "USA" => array(
      "male" => "CODE1",
      "feamle" => "CODE2",
      "null" => "CODE3"),
  "Canada" => array(
      "male" => "CODE4",
      "female" => "CODE5",
      "null" => "CODE6")
);
After that, you could access the codes by
$value = $lookupTable[$_POST['country'][$_POST['gender']];
Note that PHP's syntax for defining huge arrays like this is kind of messy. That's likely by design, as it's generally frowned upon to hard-code large amounts of data into your app. It makes the code difficult to maintain.

Your *real* best bet would be to create that multidimensional array by reading an external file or data source, or to write a function that queries that source directly. Parsing a .CSV file is a nice simple and lightweight option for your use case. A database is overkill, unless you're already using one elsewhere in your app.

That said, there's nothing inherently wrong about doing this with a massive if/else or switch statement, but it's probably needlessly messy and slow for the case you're describing.

Lemme know if you need any more explanation from the above example, in case you haven't worked with multidimensional arrays before...
posted by schmod at 10:42 AM on April 4, 2012


Is there a pattern to the data?

Eg.

UK: male = 1, female=2, nothing =3
US: male = 7, female=8, nothing =9

etc

in those cases I would give UK and id of 1 and US of 7

male would have a value of 0, female =1, nothing =2

then $value = $country_id+$gender_id;

Obviously if the data isn't numerical or there is no pattern to the data its a little more difficult but if you don't want to use a database for it you could still assign numerical values to each of the countries and gender options and use them to calculate the array position of the correct value (essentially what schmod wrote above but using numerical indexes - less typing. )
posted by missmagenta at 10:49 AM on April 4, 2012


Keep going, that's still not enough information. Can the result values be calculated based on the country + gender? i.e. if you knew that the results you want are
US male=1 female=2 nothing=3
Canada male=4 female=5 nothing=6
...and so on, then your code could be something like this pseudocode:

countries = ["US", "Canada", ...]
results = (find the position of the selected country in that array, multiply by three, add one if male or two if female or three if no gender selected). (You could easily get the array position by passing the country select box's selectedIndex to the server instead of the field value.)

But what are you planning to do with $value after you fill it? If you're just trying to record the combination of selections the user made, you'd likely be better off storing $country and $gender separately than by laboriously constructing some third variable that combines the two choices.
posted by ook at 10:49 AM on April 4, 2012


Response by poster: I want to use the final value for another script.
For example the US has X women and Y men, with a total population of Z. So, if the user selects the US and Men the script would run using Y instead of X or Z.
schmod: "Your *real* best bet would be to create that multidimensional array by reading an external file or data source, or to write a function that queries that source directly. Parsing a .CSV file is a nice simple and lightweight option for your use case."
That seems exactly what I was looking for. I haven't worked with multidimensional arrays before but now I can look them up!
posted by Memo at 11:07 AM on April 4, 2012 [1 favorite]


This sounds like a database question to me. SELECT "population" FROM "statistics" WHERE "country" = 'United States' AND "gender" = 'male'.
posted by Nothing at 1:51 PM on April 4, 2012


Response by poster: I was able to make it work with a csv file and a multidimensional array, yay! Thanks everyone.
posted by Memo at 3:53 PM on April 4, 2012 [1 favorite]


« Older Cardio/alcohol   |   A Passover without the brisket Newer »
This thread is closed to new comments.