1

I created an HTML table containing radio fields using a multidimensional array.

How can I get the selected values from the form submission?

My current code:

$cakedata = array(
    array("shape" => "Heart",       "flavor" => "Chocolate",    "toppings" => "Cookies"),
    array("shape" => "Rectangle",   "flavor" =>  "Vanilla",     "toppings" =>  "Spun-sugar Flowers"),
    array("shape" => "Square",      "flavor" =>  "Lemon",       "toppings" => "Mini Chocolate Candies"),
    array("shape" => "Round",       "flavor" =>  "Cheesecake",  "toppings" => "Marshmallows")
);
echo "<form action = 'diycake.php' method = 'post'>";
echo "<table><table border = '1'>";
echo "<tr>";
    echo "<th> Cake Shape </th>";
    echo "<th> Cake Flavor </th>";
    echo "<th> Cake Toppings </th>";
$i = 0;
foreach($cakedata as $row => $innerArray){
    foreach($innerArray as $innerRow => $value){
        if($i==0){
            echo "<tr>";
        }
        echo "<td><input type ='radio' name ='radio".$i."'>".$value."</td>";
        if($i==2){  
            echo "</tr>"; 
            $i=-1;
        }
        $i++;
    }
}
echo "</tr>";
echo "</table><br>";
echo "<input type = 'submit' name = 'submit' value = 'Submit'>";
echo "</form>";
echo '<pre>'; print_r($cakedata); echo '</pre>';

How do I receive the user's selections?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • On your `diycake.php` you should check, `isset($_POST['submit'])`, if the form was sent. The value from the radio button is also in the `$_POST[]` variable, accessible by it's name. So you could do a loop, and check if `isset($_POST['radio' . $i])`. If it's set, the value of the radio button is in this variable. You would probably also include the `value`-attribute in the radio-button tag, to get the actual value. Otherwise it will be empty for all buttons – Raphi1 Apr 24 '23 at 19:36

2 Answers2

0
<html>
    <head>
        <title>DIY Cake</title>
    </head>
    <body>
        <h1>D-I-Y Cake</h1>
        <?php
        $cakedata = array(
                        array("shape" => "Heart",       "flavor" => "Chocolate",    "toppings" => "Cookies"),
                        array("shape" => "Rectangle",   "flavor" =>  "Vanilla",     "toppings" =>  "Spun-sugar Flowers"),
                        array("shape" => "Square",      "flavor" =>  "Lemon",       "toppings" => "Mini Chocolate Candies"),
                        array("shape" => "Round",       "flavor" =>  "Cheesecake",  "toppings" => "Marshmallows")
                );
        echo "<form action = 'diycake.php' method = 'post'>";
        echo "<table><table border = '1'>";
        echo "<tr>";
            echo "<th> Cake Shape </th>";
            echo "<th> Cake Flavor </th>";
            echo "<th> Cake Toppings </th>";
                $i = 0;
                foreach($cakedata as $row => $innerArray){
                    foreach($innerArray as $innerRow => $value){
                        if($i==0){
                            echo "<tr>";
                            }
                            echo "<td><input type ='radio' name ='radio".$i."' value='" . $value . "'>".$value."</td>";
                        if($i==2){  
                            echo "</tr>"; 
                            $i=-1;
                            }
                        $i++;
                    }
                }
        echo "</tr>";
        echo "</table><br>";
        echo "<input type = 'submit' name = 'submit' value = 'Submit'>";
        echo "</form>";

        ?>

    </body>
</html>

diycake.php

<?php

// check, if form was sent
if (isset($_POST['submit'])) {
  $outerNumberArray = 4; // actually the outer number of your array
  for($i = 0; $i < $outerNumberArray; $i++) {
    if (isset($_POST['radio' . $i])) {
      echo "Your value from radio" . $i . ": " . $_POST['radio' . $i] . PHP_EOL;
    }
  }
}
Raphi1
  • 322
  • 1
  • 9
0

Radio button name attributes are expected to be identical in their relative group. This way the behavior of unchecking other radio buttons in the same "family" can be automated. You shouldn't append a counter to the name values.

I recommend wrapping your cake attribute radio elements in <label> tags so that the text represents a clickable element to affect the radio button.

As a matter of best practice and improving code maintainability, create all of the table's content dynamically by referencing the columns and values in the $cakedata array. If you ever want to add or remove cells from your table, you will only need to adjust your array -- not the HTML markup. Demo of printf()

If you ever need to adjust your HTML markup, that can be simplified by declaring template strings with placeholders -- this is, again, best practice because it affords making fewer changes.

Use required on a least one of the radio buttons in each group if you want to enforce client-side validation that each radio has a selection. Client-side validation is never a replacement for server-side validation; it only improves the UX.

[clears throat] I must warn that modern web development trends indicate that some developers prefer to use a client-side language to populate HTML markup (not server-side languages, such as PHP).

(Neither of the below snippets were actually tested. Leave a comment if I've made any mistakes.)

$cakedata = [
    ["shape" => "Heart",     "flavor" => "Chocolate",  "toppings" => "Cookies"],
    ["shape" => "Rectangle", "flavor" => "Vanilla",    "toppings" => "Spun-sugar Flowers"],
    ["shape" => "Square",    "flavor" => "Lemon",      "toppings" => "Mini Chocolate Candies"],
    ["shape" => "Round",     "flavor" => "Cheesecake", "toppings" => "Marshmallows"]
];

$headings = array_keys($cakedata[0] ?? []);

$th = <<<TH
    <th>Cake %s</th>
TH;

$td = <<<'TD'
    <td><label><input type="radio" name="%1$s" value="%2$s" required>%2$s</label></td>
TD;

?>
<form action="diycake.php" method="post">
    <table border="1">
        <tr>
            <?php
            foreach ($headings as $name) {
                printf($th, htmlentities(ucwords($name)));
            }
            ?>
        </tr>
        <?php
        foreach ($cakedata as $row) {
            echo '<tr>';
                foreach ($row as $attr => $value) {
                    printf($td, htmlentities($attr), htmlentities($value));
                }
            echo '</tr>';
        }
        ?>
    </table>
    <input type="submit" name="submit" value="Submit">
</form>

When the form is submitted, the $_POST payload will have $_POST['submit'] with a value of Submit. This should be your first validation check before doing any else (don't even bother connecting to the database if the form submission doesn't pass all validations).

The $_POST array will also be expected to contain $_POST['shape'], $_POST['flavor'], and $_POST['toppings']. You can easily check that these exist with a single call of isset(), but you might as well check each with !empty() individually. For that matter, you should also confirm that the submitted values also EXIST in $cakedata. These heavy-handed validations are essential if you want to have a stable, secure application.

if (isset($_POST['submit'])) {
    $valid = true;
    foreach (array_keys($cakedata[0] ?? []) as $column) {
        if (empty($_POST[$column]) || !in_array($_POST[$column], array_column($cakedata, $column))) {
            $valid = false;
            break;
        }
    }
    // only proceed with server-side processes if the submission was completely valid.
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136