使用 PHP 会话存储和更新复选框数组


Storing and updating checkbox array with PHP sessions

我有一个注册表单,其中包含复选框形式的运动列表(从 mysql 表中提取)。在帖子中,我创建了一个会话,其中包含与可以验证的表单相关的变量。除了存储运动的复选框外,一切都按计划进行。我已经通过数组传递我的帖子值,所以这就像通过数组传递数组一样,这就是我没有任何运气的地方。我只想要从帖子到节目的检查体育。此外,如果该列表在第二次或第三次验证时更新,我希望它更新数组。代码如下,提前感谢。

邮政编码

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'])));

表单代码

        <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>&nbsp;</td>";
            $content .= '</tr>';
        }
    $content .= '
    </table>

更新!!!

我最初忘了提到我的代码在创建会话后会检查每个框,而不仅仅是选中最初选中的框。我被告知这是因为我基于我的代码的检查条件始终是正确的,所以......

取代:

foreach ($_SESSION['sport'] as $sport_id) {
            $checked = 'checked';
        }

跟:

if (in_array($sport_id, $_SESSION['sport'])) {
    $checked = 'checked';
} else {
    $checked = '';

现在,它记得两个复选框,但在每次提交后,它会立即选中我第一次检查的复选框右侧的复选框。如果我再次点击提交,它会在右侧的另一个位置。 }

首先,以下内容对我来说似乎很奇怪:

//sanitizes input and prevents sql injection attacks
foreach($_POST as $key => $value) {
    $data[$key] = filter($value);
    $_SESSION[$key] = $value;
}

这是否意味着您将$_POST中的所有内容保存到$_SESSION中?这不可能是您想要的,因为如果您在网站的另一部分使用会话获取登录信息,例如将用户名存储在 $_SESSION['username'] 中,那么有人可以通过使用"用户名"参数提交表单来覆盖这一点。所以你可能不想这样做;我建议只检查您实际想要的 POST 变量并将它们清理到您想要的位置。

我建议将您的代码更改为以下内容:

$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'];
}

这将允许用户在提交任何运动时覆盖会话中的运动。如果要在会话中允许空的运动数组,则需要将第一个 if 语句中的检查更改为类似 if (isset($_POST['submit']) 的内容,以检查表单是否已提交(并且您的提交按钮名为"提交")。

如果第一个条件失败(即,没有传递新的体育阵列),则将使用存储在会话中的运动阵列。

然后,检查运动是否被检查的代码的第二部分将是这样的:

$checked = in_array($id, $sports);
$content .= '<td><input type="checkbox" name="sport[]" value="'.$id.'" id="sport'.$id.'" '.($checked?'checked="checked':'').'>'.$name.'</td>';

(假设$id$name设置正确。

更新:还要检查 POST 中的运动数组是否真的是一个数组。