带有PHP和SQL问题的复选框

带有PHP和SQL问题的复选框,php,sql,checkbox,Php,Sql,Checkbox,我正在尝试从我的SQL数据库中显示注册人员的列表 我有一个表,每个列都输出到其中,但我遇到的问题是复选框将被更新,以显示此人是否已付款。我会检查盒子,而不是客户 到目前为止,我遇到了两个问题: 1) 当我提交更新以将复选框保存到SQL db的列中时,它不会显示正在选中的框,除非我刷新该框所在的页面并获取更新的(新存储的)选中值 2) 当我试图取消选中该框并尝试保存时,我得到一个错误,该错误表示我的paymentStatus数组为,并且未定义索引,因为没有为其分配值 我在这个问题上一直在兜圈子,我

我正在尝试从我的SQL数据库中显示注册人员的列表

我有一个表,每个列都输出到其中,但我遇到的问题是复选框将被更新,以显示此人是否已付款。我会检查盒子,而不是客户

到目前为止,我遇到了两个问题:

1) 当我提交更新以将复选框保存到SQL db的列中时,它不会显示正在选中的框,除非我刷新该框所在的页面并获取更新的(新存储的)选中值

2) 当我试图取消选中该框并尝试保存时,我得到一个错误,该错误表示我的paymentStatus数组为,并且未定义索引,因为没有为其分配值

我在这个问题上一直在兜圈子,我无法想象这真的有这么难,所以我想一定有更好的方法来完成我正在努力做的事情

这是我目前的代码:

谢谢你的帮助


完整代码:

<?php
    require_once ('functions.php');
    require_once ('includes/cred.php');

    $query = $conn->prepare("SELECT * FROM sponsors");
    //$query->bindParam(":idnum", "1");
    $query->execute();
    $notPaid = $query->fetchAll();


    if (isset($_REQUEST["sponsorUpdate"])) {
        //Create Sessions
        $array = $_POST;
        foreach ($array as $key => $value) {
            $_SESSION[$key] = $value;
        }

        if(isset($_POST['paymentStatus'])) {
            $payment = $_POST['paymentStatus'];
            foreach($payment as $value) {
                $stmt = $conn->prepare("UPDATE sponsors SET paid=1 WHERE id = $value");
                $stmt->execute();
            }
        } else {
            $payment = $_POST['id'];
            foreach($payment as $value) {
                $stmt = $conn->prepare("UPDATE sponsors SET paid=0 WHERE id = $value");
                $stmt->execute();
            }
        }
    }

?>
<html>

<head>
</head>
<body>
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
<table border="1" cellspacing="0" cellpadding="10">
    <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Company Name</th>
        <th>Email Address</th>
        <th>Phone Number</th>
        <th>Address</th>
        <th>City</th>
        <th>State</th>
        <th>Zipcode</th>
        <th>Sponsor Level</th>
        <th>Payment Received</th>
    </tr>
    <?php 

            foreach ($notPaid as $row) {
            $phone = preg_replace('/(\d{3})(\d{3})(\d{4})/', '($1) $2-$3', $row['phone']);
        ?>
    <tr>
        <td><?php echo $row['fname']; ?></td>
        <td><?php echo $row['lname']; ?></td>
        <td><?php echo $row['cname']; ?></td>
        <td><?php echo $row['email']; ?></td>
        <td><?php echo $phone; ?></td>
        <td><?php echo $row['address']; ?></td>
        <td><?php echo $row['city']; ?></td>
        <td><?php echo $row['state']; ?></td>
        <td><?php echo $row['zip']; ?></td>
        <td><?php echo $row['sponsorLevel']; ?></td>
        <td><input name="paymentStatus[]" type="checkbox" value="<?php echo $row['id']; ?>" <?php if ($row['paid'] == 1) echo 'checked="checked"'; ?></td>
    </tr>
    <?php
     } ?>
</table>
    <input type="submit" name="sponsorUpdate" value="Save Changes" />
</form>
</body>
</html>

1) 当我提交更新以将复选框保存到其列中时
在SQL db中,除非刷新,否则它不会显示正在选中的框
然后它进入的页面,并获取更新(新存储)的值
当然可以

这是因为在每次页面加载时,您首先执行
选择
,然后执行
更新
。切换此操作的顺序<代码>使用任何新的用户输入(如果有)更新数据库,然后选择
向用户显示那些可能更新的更改

2) 当我试图取消选中该框并尝试保存时,我得到一个错误 也就是说我的paymentStatus数组是一个未定义的索引,因为有 没有为其指定值

这是意料之中的。如果您在Firebug中查看HTTP请求,您将看到未选中的复选框不会随请求一起发送。这意味着不会设置
$\u POST['paymentStatus']
。在试图将该复选框的值保存到数据库时,您需要在代码中说明这一点

如果要测试复选框是否已选中,则应执行以下操作:

$paymentStatus = isset($_POST['paymentStatus']);
变量
$paymentStatus
将包含
true
false
值,具体取决于发送表单时是否选中了复选框。这是因为如果选中该选项,则输入的
名称将与请求一起发送,其值为
on
。如果它没有被选中,它就根本不会被发送,也不会出现在
$\u POST

下面是一个演示上述内容的快速示例:

if (isset($_REQUEST["sponsorUpdate"])) 
{
    // if the paymentStatus parameter is sent with the HTTP request
    // the $paymentStatus variable will be set to 1 which indicates that
    // the checkbox was checked.  If it was not checked, it will have a
    // value of 0.

    $paymentStatus = isset($_POST['paymentStatus']) ? 1 : 0;

    // always test your input before putting data into a database
    // the bindParam() method should take care of this for us, but it's
    // good practice anyway

    if ($paymentStatus === 0 || $paymentStatus === 1)
    {
        $stmt = $conn->prepare("UPDATE sponsors SET paid=?");
        $stmt->bindParam(1, $paymentStatus);
        $stmt->execute();

        // test for SQL errors ...
    }
}
我认为您的解决方案还有最后一个问题,那就是您依赖的两件事对您的复选框没有帮助:

  • 与复选框关联的GET或POST参数的值,如果选中,则始终以“on”的值发送到服务器,如果未选中,则根本不发送。
    属性未发送,因此服务器将永远无法获取要更新的行的ID

  • 由于不会向服务器发送任何内容来指示未选中复选框,因此在保存所有表单输入时,您将无法使用该输入作为循环键。不幸的是,您需要重新思考您的设计


  • 通过使用外部变量构建SQL语句,您将面临SQL注入攻击。此外,任何带有单引号的输入数据,如“O'Malley”的名称,都会破坏您的SQL查询。请了解如何使用参数化查询(最好是PDO模块)来保护您的web应用程序。有许多详细的例子。您还可以查看替代方案和危险解释。这看起来确实像PDO模块。代码只是缺少将
    $value
    变量绑定到参数的
    bindParam
    语句。我最初的实现包括bindParam语句,但是,为了测试它是否有效,我已经包括了基本变量。目前这一切都是在本地开发的,所以注入不是一个问题,因为我仍处于早期阶段,并试图让基本功能正常工作。不过,我希望原始问题得到回答,而不是寻求帮助确保这一点。感谢Cypher,1是有意义的。对于2,我想这是我真正的问题,我该怎么解释呢。我知道它在做什么,但我还没有想出一个好的解决办法。我补充了一点关于你问题的第二部分。如果您需要进一步的澄清,请告诉我。设置此选项有效,但只会让我了解我的原始问题。如果复选框为all is fine,它将运行If语句中的代码。else语句中仍然存在未定义索引的问题。可能会同时选中多个框,因此我需要它能够运行所有迭代并更新它们的行。我不知道如何在没有未定义索引的情况下为其提供关联的行id?我不确定我是否完全理解您的评论。但是,我已经更新了答案,以演示如何处理表单中的复选框。
    在else语句中仍然存在未定义索引的问题。
    如果尝试访问不存在的数组索引,将出现PHP错误。您需要使用
    isset()
    array\u key\u exists()
    进行测试。您甚至可以在超全局上使用
    filter\u input()
    函数来检索值,而不会触发该错误。