Reputation: 13
I have a signup form with a list of sports in checkbox form (pulled from a mysql table). On post, I create a session with variables pertaining to the form that can be validated. Everything works as planned except storing the checkboxes of the sports. I am already passing my post values through an array so it's like passing an array through an array and that's where I'm not having any luck. I just want the checked sports from post to show. Additionally, if that list is updated on a 2nd or 3rd validation I want that to update the array. Code is as follow, thanks in advance.
Post code
if(isset($_POST['signup']) == 'Finish') {
//start session to store variables for post-submit validation
session_start();
//sanitizes input and prevents sql injection attacks
foreach($_POST as $key => $value) {
$data[$key] = filter($value);
$_SESSION[$key] = $value;
}
$_SESSION['sport'] = array_unique(array_values(array_merge($_SESSION['sport'], $data['sport'])));
Form code
<table class="signup_sportstable" border="0" cellpadding="0" cellspacing="4">';
$result = mysql_query("SELECT * FROM sports ORDER BY sport ASC");
$i = 0;
$max_columns = 3;
while($row = mysql_fetch_array($result)) {
foreach ($_SESSION['sport'] as $sport_id) {
$checked = 'checked';
}
// make the variables easy to deal with
extract($row);
// open row if counter is zero
if($i == 0)
$content .= '<tr>';
// make sure we have a valid product
if($sport != "" && $sport != null)
$content .= '<td><input type="checkbox" name="sport[]" value="'.$sport_id.'" id="sport[]" '.$checked.'>'.$sport.'</td>';
// increment counter - if counter = max columns, reset counter and close row
if(++$i == $max_columns) {
$content .= '</tr>';
$i=0;
} // end if
} // end while
// clean up table
if($i > 0) {
for($j=$i; $j<$max_columns;$j++) $content .= "<td> </td>";
$content .= '</tr>';
}
$content .= '
</table>
Update!!!
I forgot to mention initially that my code checks every box once the session is created, rather than just checking the boxes that were initially checked. I was informed this was because my checked condition based on my code was always true,so...
Replaced:
foreach ($_SESSION['sport'] as $sport_id) {
$checked = 'checked';
}
With:
if (in_array($sport_id, $_SESSION['sport'])) {
$checked = 'checked';
} else {
$checked = '';
Now, it remembers two checkboxes but after every submit it checks the one immediately to the right of the one i checked the first time. If I hit submit again, its another spot to the right. }
Upvotes: 0
Views: 2942
Reputation: 995
First of all, the following seems odd to me:
//sanitizes input and prevents sql injection attacks
foreach($_POST as $key => $value) {
$data[$key] = filter($value);
$_SESSION[$key] = $value;
}
Does this mean that you're saving everything in $_POST
to your $_SESSION
? That can't be what you want, since if you're using your session in another part of your site for login information, and for instance store the username in $_SESSION['username']
, then someone can override this with submitting your form with a 'username' parameter. So you probably don't want to do that; I'd suggest just checking for the POST variables you actually want and sanitize them to where you want them.
I'd suggest changing your code to something like:
$sports = array();
if (isset($_POST['sport']) && is_array($_POST['sport'])) {
foreach ($_POST['sport'] as $sport) {
if (is_numeric($sport)) // example sanitation, since only numeric ids are allowed
$sports[] = $sport;
}
$_SESSION['sports'] = $sports;
} elseif (isset($_SESSION['sports'])) {
$sports = $_SESSION['sports'];
}
This will allow the user to override the sports in the session if they submit any sports. If you want to allow an empty sports array in the session, you'd want to change the check in the first if-statement to something like if (isset($_POST['submit'])
, to check if the form was submitted (and your submit button is named 'submit').
If the first condition fails (i.e., there's no new sports array passed), the sports array that was stored in the session will be used.
Then, your second part of the code to check if a sport was checked, would be something like:
$checked = in_array($id, $sports);
$content .= '<td><input type="checkbox" name="sport[]" value="'.$id.'" id="sport'.$id.'" '.($checked?'checked="checked':'').'>'.$name.'</td>';
(Assuming that $id
and $name
are set properly.)
Update: Also check whether the sport array from POST
is actually an array.
Upvotes: 1