【问题标题】:Insert array where checkboxes are checked在选中复选框的位置插入数组
【发布时间】:2016-05-07 15:27:37
【问题描述】:

作为 PHP 和 MySQL 的新手,我在这里阅读了很多东西。 This post 是我能找到的与我的问题相关的最接近的问题。我从解决方案中借了一些,但它只让我到目前为止。

我用来自SELECT 语句的表数据填充了一个表单,目前为 15 行。结果中的每一行都有一个复选框和相应的数据。表单中还有一个文本区域。

我需要将来自 textarea 的文本输入以及与复选框关联的 Case_NoClient_No 插入到另一个表中...仅在选中复选框的位置。每行只有文本相同。 INSERT 中不应包含任何未选中的复选框。

我意识到答案可能是某种循环,但我没有太多从循环插入的经验,只显示循环中的数据。

这是我的表格:

<form method="post" name="group_note" action="group_test.php?Counselor=<?php echo $_GET['Counselor'];?>"/>
<table border="1" width="650" cellpadding="5" cellspacing="0" bordercolor="#999999">
<tr><th>Group Note</th></tr>
<tr><td><textarea name="Note" rows="10" cols="115"></textarea></td></tr>
<tr><th align="left">Select clients below to receive this group note &nbsp; <input type="submit" value="Add Group Note"></th></tr>
</table>
<table border="1" cellpadding="5" cellspacing="0" bordercolor="#999999">
<thead>
  <tr>
    <th bgcolor="#009999">Select</th>
    <th bgcolor="#009999">Name</th>
    <th bgcolor="#009999">Case No.</th>
    <th bgcolor="#009999">Client No.</th>
    </tr>
  </thead>
  <tbody>
<?php foreach ($dbh -> query($sql) as $row) { ?>        
<tr> 
        <td><input type="checkbox" name="groupselect[]" value="<?php echo $row['Case_No'];?>" /></td>
        <td><?php echo $row['FirstName']. " " . $row['LastName']; ?></td>
        <td><?php echo $row['Case_No']; ?></td> 
        <td><?php echo $row['Client_No']; ?><input type="hidden" name="Client_No" value="<?php echo $row['Client_No']; ?>"/></td>

<?php  }  ?>
</tbody>
</table>
    <input type="hidden" name="MM_insert" value="group_note">
</form>

还有插入语句:

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "group_note")) {
try
    {
        $dbh = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_database; charset=utf8", $mysql_username, $mysql_password);
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $insertGroup = array();
        foreach ($_POST['groupselect'] as $i => $value) {
        $GroupNote_CaseNo=$_POST['groupselect'][$i];
        $GroupNote_ClientID=$_POST['Client_No'][$i];
        $GroupNote=$_POST['Note'];
        $insertGroup[]="(".$GroupNote_CaseNo.", ".$GroupNote_ClientID.", ".$GroupNote.")";
        $Note = "INSERT INTO group_note GroupNote_CaseNo, GroupNote_ClientID, GroupNote VALUES ". implode(", ", $insertGroup). "GroupNote_CaseNo=VALUES(GroupNote_CaseNo), GroupNote_ClientID= VALUES(GroupNote_ClientID), GroupNote=VALUES(GroupNote)";
        $stmt->execute();
        $stmt->closeCursor();       
    }
    }
    catch (Exception $e)
    {
    $message = 'Something not working right!!';
    }
}

当我选择两个或三个复选框并插入一些文本时,在提交时我会从var_dump($_POST['groupselect'])得到这个结果

array(3) { [0]=> string(22) "(1518-R, 4, This note)" [1]=> string(22)
"(1534-R, 3, This note)" [2]=> string(22) "(4062-R, 3, This note)" }

ClientNo 只显示一个数字,它们是三个数字长。如果我删除 $GroupNote_ClientID=$_POST['Client_No'] 后面的 [$i],我将获得所有三位数字,但只能从选中的第一个复选框行中获得:

array(3) { [0]=> string(22) "(1518-R, 4, This note)" [1]=> string(22) 
"(1534-R, 3, This note)" [2]=> string(22) "(4062-R, 3, This note)" }

在任何情况下,表中都没有插入任何内容。根据变量语法,PHP 错误日志会显示“未定义变量:insertGroup”和/或“未定义变量:insertGroup”。

另外,我知道$_POST 变量的危险。我的数据库仅供内部使用,在我们的 Intranet 上。没有外部访问权限。

【问题讨论】:

  • 如果您费心阅读 MySQL 的 INSERT 语法,并且实际上费心检查您的查询调用是否真的成功,您就会被告知您的 sql 语法错误。但相反,你选择了“不会出错”的编程学校,现在你正在为此受苦。在处理外部资源时,永远不要永远假设成功。始终假设失败,检查失败,并将成功视为惊喜。

标签: php mysql arrays checkbox


【解决方案1】:

ClientNo 只显示一位数字,它们是三位数。如果我删除 $GroupNote_ClientID=$_POST['Client_No'] 之后的 [$i],我将获得所有三位数字,但仅从选中的第一个复选框行中获得

您在保存值的隐藏输入字段上使用了name="Client_No" - 您错过了用于复选框的[],因此您只能获得最后一个值,而不是作为数组,而只是一个字符串。通过数字索引访问字符串会返回其单个字符。

现在将[] 添加到隐藏输入字段的名称中,您将不会在这里完成。对于type=checkbox,只有输入检查时才发送一个值;但 所有 的隐藏字段将被发送。而且由于结果数组的索引是自动生成的,因此您将获得复选框值和隐藏输入值之间的差异。为避免这种情况,您可以预先指定索引,将输入字段命名为 name="foo[0]"name="foo[1]" 等。如果您对这两个字段都这样做,您将在数组中得到正确匹配的值。

但是您仍然必须考虑到复选框数组中的索引可能“丢失”,而不是设置。所以你应该循环遍历隐藏的输入值数组——这将设置所有索引,没有间隙。然后使用当前索引来检查复选框数组是否有与给定键(isset)对应的元素。

您也可以使用客户编号来代替数字数组索引。

如果您将复选框命名为 name="foo[igf]"、name="foo[dkh]" 等,那么您将不再需要隐藏的输入字段 - 每个选中的复选框将自动与其客户编号相关联。

【讨论】:

  • 将 [] 添加到 ClientName 输入肯定有效!我对你其余的回答感到很困惑。因为复选框是动态生成的,所以我不知道如何通过重命名输入字段来预先指定索引。生成的行数在一种情况下可能是 15,在另一种情况下可能是 8,在另一种情况下可能是 2。虽然我通过检查 some 框并跳过其他框进行了测试,但结果数组似乎跟上了正确的值。我了解您对数字数组的意图,如果可以的话,表中有一个自动递增的索引。
  • 也许我应该有资格“......输入肯定有效”。尽管var_dump $insertGroup 的输出显示了所有需要插入的数据(CaseNo, ClientNo, GroupNote...[0]=> string(24) "(1518- R, 336, This note)"。在我无法辨别的地方发生了故障。php_errors 日志中没有显示任何内容。
  • 也许您应该检查可能的异常实际上要说什么,而不是仅仅用您自己的通用错误消息替换它们。
  • 当然你是对的,我没有花一分钟意识到这一点。 PDO Exception $e 的输出是“我们无法处理您的请求。请稍后再试”。非常神秘,也不太有用。我启用了 MySQL 日志记录,但只能说出来
  • (续)我启用了 MySQL 日志记录,但只能说 INSERT 没有到达服务器。只有 SELECT 出现在日志中。其他表单上的 INSERT 正在工作并显示在日志中。现在正在搜索错误消息的一些提示。
【解决方案2】:

所以,我终于让它工作了。首先,@CBroe 关于在表单中将[] 添加到ClientNo 的建议选择了我需要的第二个变量。另一部分涉及使用PREPARE 语句的占位符更改INSERT 语句。我可以为此归功于@Marc B吗?

我也绑定了值,但我确实认为接受$_POST 输入是不安全的。我唯一的辩护是这不是一个面向公众的数据库。

这是结果(表格没有改变,它仍然在原来的问题中),与原来的比较:

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "group_note")) {
try
{
$dbh = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_database; charset=utf8", $mysql_username, $mysql_password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$insertGroup = array();
foreach ($_POST['groupselect'] as $i => $value) {
$GroupNote_CaseNo=isset($_POST['groupselect']) ? ($_POST['groupselect'][$i]) : null;
$GroupNote_ClientID=isset($_POST['ClientNo']) ? ($_POST['ClientNo'][$i]) : null;
$GroupNote=$_POST['Note'];
$insertGroup[]="(".$GroupNote_CaseNo.",".$GroupNote_ClientID.",".$GroupNote.")";
$Note = 'INSERT INTO group_note (GroupNote_CaseNo,GroupNote_ClientID,GroupNote) VALUES (:GroupNote_CaseNo, :GroupNote_ClientID, :GroupNote)';
$stmt=$dbh->prepare($Note);
$stmt->bindValue(':GroupNote_CaseNo', ($_POST['groupselect'][$i]));
$stmt->bindValue(':GroupNote_ClientID', ($_POST['ClientNo'][$i]));
$stmt->bindValue(':GroupNote', $_POST['Note']);
$stmt->execute();
$stmt->closeCursor(); 
}
}
catch (Exception $e)
{
$message = $e;
}
}  

绑定中的一些括号可能是不必要的,但我不是开发人员。它对我有用,希望对某人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 2017-06-23
    • 2017-07-17
    • 2013-05-31
    • 2019-05-22
    • 1970-01-01
    相关资源
    最近更新 更多