📖 PHP Collecting Array Data from a Form
This article deals with the issue of collecting array data from a form. While there are a number of ways of dealing with this, here is a possible solution.
We are given a problem of having a form with a list of checkboxes. These checkboxes are created from a data table in a database. We need to query the database to get the original list of data for the user. When the user submits the form they are required to select between 1 and 3 items form the list. This scenario uses a list of genres from the chinook database. Because we intend to collect multiple selections from this list, we need to prepare the form field to build an array of items. we simply add square brackets [ ] to the name attribute of the list.
The genres will be collected in an array from the registration form.
<li>
<label>
<input type="checkbox" name="genres[]" value="$GenreId" $checked>
$Name
</label>
</li>
The brackets on the name="genres[]" is to create the genres array.
Build the genre list from the Genre table in the database.
$genreList = '<ul style="list-style: none;">';
// connect to database
$conn = mysqli_connect("localhost", "phpstudent", "Itse1406",'chinook');
$sql_genre = "SELECT `GenreId`, `Name` FROM `Genre` WHERE 1;";
$result_genre = mysqli_query($conn, $sql_genre);
// loop through database
while($newArray_genre = mysqli_fetch_array($result_genre)){
$GenreId = $newArray_genre['GenreId'];
$Name = $newArray_genre['Name'];
// build checkbox list
$genreList .= <<<HERE
<li>
<label>
<input type="checkbox" name="genres[]" value="$GenreId">
$Name
</label>
</li>\n
HERE;
}
$genreList .= "</ul>\n";
Use $genreList in the form output.
<form method="post" action="register.php">
// other form elements
$genreList
// more form elements
<input type="submit" name="submit" value="Register">
<form>
When the form is submitted, you'll need to check the the $_POST array for the genres[] value(s) and see how many there are. You should only allow between 1 and 3 genres. Too many or too few should flag an error along with other validation could cause the form to be reloaded with sticky data. Because you need to build the genre list in case of a validation error, we will build the list and check for matches at the same time.
// start building the genre list. you'll need it if the form has to be sent back to the user
$genreList = '<ul style="list-style: none;">';
// query the database to get the genre list
$conn = mysqli_connect("localhost", "phpstudent", "Itse1406",'chinook');
$sql_genre = "SELECT `GenreId`, `Name` FROM `Genre` WHERE 1;";
$result_genre = mysqli_query($conn, $sql_genre);
while($newArray_genre = mysqli_fetch_array($result_genre)){
$GenreId = $newArray_genre['GenreId'];
$Name = $newArray_genre['Name'];
$checked = NULL;
// pull the genres from the $_POST array
if (filter_has_var(INPUT_POST, 'genres')) {
// genres are listed in the genres array in the $_POST array (multidimensional array)
// use the foreach loop to step through the genres[] array
foreach ($_POST['genres'] as $key => $value) {
// check to see if any genres from the data match the user selected genres ($_POST['genres'])
if ($GenreId == $value) {$checked = "checked";}
}
// if any selected genres match the data add checked to make the checkboxes sticky
if(!is_null($checked)){
// count the selected genres
$genreCount++;
}
}
// build the list of checkboxes
$genreList .= <<<HERE
<li>
<label>
<input type="checkbox" name="genres[]" value="$GenreId" $checked>
$Name
</label>
</li>\n
HERE;
}
$genreList .= "</ul>\n";
// echo $genreList to populate the form
// check to see how many genres you have submitted in $_POST
if (($genreCount < 1) || ($genreCount > 3)) {
$genreError = "<span class='error'> Please select between 1 and 3 genres</span>";
$valid = false;
}
Again, the $genreList variable can be used to populate the form whether it's the first time the user visits, or if the page has to be returned to the user due to data validation errors (sticky).
To see an example of this code at work, visit the example page.