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.
}