【问题标题】:Checkbox with PHP and SQL problems带有 PHP 和 SQL 问题的复选框
【发布时间】:2014-05-16 23:21:17
【问题描述】:

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

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

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

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

2) 当我试图取消选中该框并尝试保存时,我收到一条错误消息,指出我的 paymentStatus 数组是未定义的索引,因为没有为其分配值。

我一直在这个问题上兜圈子,我无法想象它真的这么难,所以我认为必须有更好的方法来完成我想做的事情。

这是我当前的代码:http://pastebin.com/bgAtYqbL

感谢您的帮助。


完整代码:

<?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>

【问题讨论】:

  • 通过使用外部变量构建 SQL 语句,您将面临 SQL 注入攻击。 此外,任何带有单引号的输入数据,例如“O 'Malley",会炸毁你的 SQL 查询。请了解如何使用参数化查询(最好使用 PDO 模块)来保护您的 Web 应用程序。 This question 有很多详细的例子。您还可以查看bobby-tables.com/php 了解替代方案和危险说明。
  • 这看起来确实像 PDO 模块。该代码只是缺少将$value 变量绑定到参数的bindParam 语句。 php.net/manual/en/pdostatement.bindparam.php
  • 我最初的实现包括 bindParam 语句,但是,为了测试这是否有效,我已经包含了基本变量。目前这一切都在本地开发,所以注入不是问题,因为我仍处于早期阶段并试图让基本功能正常工作。但是,我希望回答原始问题,而不是寻求帮助来确保这一点。

标签: php sql checkbox


【解决方案1】:

1) 当我提交更新以将复选框保存到它的列中时 在 SQL 数据库中,除非我刷新,否则它不会显示被选中的框 然后它去的页面并获取更新的(新存储的)值 已检查。

这是因为在每次页面加载时,您首先执行SELECT,然后执行UPDATE。切换这个顺序。 UPDATE 带有任何新用户输入(如果有)的数据库,然后 SELECT 向用户显示那些可能更新的更改。

2) 当我尝试取消选中该框并尝试保存时,出现错误 说我的 paymentStatus 数组是和未定义的索引,因为有 没有给它赋值。

这是意料之中的。如果您查看类似 Firebug 中的 HTTP 请求,您会看到未选中的复选框没有随请求一起发送。这意味着不会设置$_POST['paymentStatus']。尝试将该复选框的值保存到数据库时,您需要在代码中考虑这一点。

如果你想测试复选框是否被选中,这样的事情应该可以完成:

$paymentStatus = isset($_POST['paymentStatus']);

变量$paymentStatus 将包含truefalse 值,具体取决于发送表单时是否选中了复选框。这是因为如果它被选中,inputname 将与值为on 的请求一起发送。如果不检查,则根本不会发送,也不会出现在$_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 ...
    }
}

我在您的解决方案中看到了最后一个问题,那就是您依赖的两件事对您的复选框无济于事:

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

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

【讨论】:

  • 感谢 Cypher,1 是有道理的。对于 2,我想这是我的实际问题是我该如何解释这一点。我明白它在做什么,但我还没有想出一个好的解决方案。
  • 我添加了更多关于您问题的第二部分的内容。如果您需要进一步说明,请告诉我。
  • 设置这项工作但只能让我了解我原来的问题。如果选中该框一切正常,它会在我的 if 语句中运行代码。 else 语句中仍然存在未定义索引的问题。可能会同时选中多个框,因此我需要它能够运行所有迭代并更新它们的行。我不确定如何在没有未定义索引的情况下为其提供关联的行 ID?
  • 我不确定我是否完全理解您的评论。但是,我已经更新了答案,以演示我如何处理表单中的复选框。
  • There is still an issue of undefined index within the else statement. 如果你试图访问一个不存在的数组的索引,你会得到一个 PHP 错误。您需要使用isset()array_key_exists() 进行测试。您甚至可以在超全局变量上使用 filter_input() 函数来检索值而不会触发该错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 2011-09-11
相关资源
最近更新 更多