【问题标题】:PHP - Get all values that has been checked in checkbox and combine it in one arrayPHP - 获取已选中复选框的所有值并将其组合在一个数组中
【发布时间】:2019-02-12 11:28:12
【问题描述】:

我从 HTML 表单中获取值没有问题,但我的问题是如何将我得到的所有值合并到一个数组中?

示例:

Quantity[]CheckBox[] 分开。如果复选框已被选中,则只有它的所有值(Pizza ID、名称、价格和数量)应传输到一个数组中。

片段代码:

<tbody>
    <?php 
    $Row = 0;
    while ($Row = mysqli_fetch_array($Retrieval_Query, MYSQLI_ASSOC)){
        $pizzaID = $Row['pizzaID'];
        $pizzaName = $Row['pizzaName'];
        $pizzaPrice = $Row['pizzaPrice'];
    ?>
    <tr>
        <td><?php echo $pizzaID; ?></td>
        <td><?php echo $pizzaName; ?> </td>
        <td><?php echo $pizzaPrice; ?> </td>
        <td><input type = "number" name = "Quantities[]" placeholder = "0"/></td>
        <td><input type = "checkbox" name = "CheckBox[]" value="<?=$pizzaID?>,<?=$pizzaName?>,<?=$pizzaPrice?>" placeholder = "0"/></td>
    </tr>
    <?php } ?>
</tbody>
</table>
</form>         
<button type="submit" form="form1" value="Atc" name="atc" class="btn btn-warning">Add to Cart</button>

后端:

<?php
$values = array();
$quantities = array();

if(isset($_POST['atc'])){

//Operation to retrieve all values from HTML CheckBox[] and Quantities[] since they are separated inputs
//And push all values that has been retrieved into same array
foreach($_POST['CheckBox'] as $key => $value){
    array_push($values, $value);
}
foreach($_POST['Quantities'] as $key => $value){
    array_push($values, $value);
}

当前输出:

期望的输出:

如何达到预期的输出?我的技术是从 HTML 中获取值吗 (2个分隔数组)对吗?如何使所有值组合在一起 只有一个数组?

【问题讨论】:

  • 我想弄清楚为什么你首先要使用两个不同的数组,现在你想组合它们
  • 我怎样才能一次得到它们?输入数字字段和复选框?

标签: php arrays associative-array


【解决方案1】:

如果您像 PHP 在脚本中看到的那样查看 POST 数据,您将更好地了解正在发生的事情。在 PHP 的顶部添加:

print_r($_POST);
die();

你会看到:

Array
(
    [Quantities] => Array
        (
            [0] => 23
            [1] => 
            [2] => 33
        )

    [CheckBox] => Array
        (
            [0] => 1,Hawaiian,150
            [1] => 3,Four Cheese,300
        )

接下来,array_push 只是将元素附加到数组的末尾。所以你只是一个接一个地加入这两个数组,而没有保留元素相互关联的事实。

下一个问题是,如果未选中复选框,则根本不会出现在 POSTed 数据中。您可以看到Checkbox 数组中只有 2 个元素,即使表单中有 5 个披萨。这意味着您无法使用键连接 Quantities 数组和 CheckBox 数组中的元素。 Quantities中的key 1对应Bacon and Cheese,但是CheckBox中的key 1对应Four Cheese

我看不到使用您当前的方法解决此问题的简单方法。

但是退后一步 - 您真的想将价格发布到您的处理代码吗?如果我在浏览器中编辑表单并将价格设置为“1”或“0”怎么办?您永远不应该相信来自浏览器的数据,而且您的数据库中已经有了这些数据。

如果数量为 0,您真的关心订单中的披萨吗?您可以取消该复选框,因为在数量字段中输入一个数字可以控制他们是否获得该披萨。

这是另一种方法:

<?php while ($Row = mysqli_fetch_array($Retrieval_Query, MYSQLI_ASSOC)) { ?>
<tr>
    <td><?php echo $Row['pizzaID']; ?></td>
    <td><?php echo $Row['pizzaName']; ?></td>
    <td><?php echo $Row['pizzaPrice']; ?></td>
    <td>
        <!-- include the ids, we can refer to those for each quantity -->
        <input type="hidden" name="ids[]" value="<?php echo $Row['pizzaID']; ?>"/>
        <input type="number" name="Quantities[]" placeholder = "0"/>
    </td>
</tr>
<?php } ?>

现在在您的后端,您可以执行以下操作:

foreach ($_POST['Quantities'] as $key => $value) {

    if (empty($value) || $value == 0) {
        // wasn't ordered!  Skip to the next.
        continue;
    }

    $id = $_POST['ids'][$key];
    // Now you know they want $value of pizza id $id.  You can look
    // up the price, name, etc, from your DB, same as you did to 
    // display them on the form in the first place.
}

旁注 - 它可能只是您的真实代码和您在 SO 上的问题之间的复制粘贴问题,但提交按钮应位于 &lt;/form&gt; 标记内。

【讨论】:

    【解决方案2】:

    您可以使用“关联数组”样式来命名表单输入,如 PHP 文档中所述:

    http://www.php.net/manual/en/faq.html.php#faq.html.arrays

    使用您唯一的 pizzaID 作为两个输入数组的键:

    (包括一个字符串元素(我在这里使用了id_)以确保它是我们稍后将使用的字符串键,因为数组函数对于数字索引数组的工作方式不同)

    while ($Row = mysqli_fetch_array($Retrieval_Query, MYSQLI_ASSOC))
    {?>
      <input type = "number" name = "Quantities[id_<?=$pizzaID?>]" id="qty<?php echo $cnt?>" placeholder = "0"/>
      <input type = "checkbox" name = "CheckBox[id_<?=$pizzaID?>]" data-cnt="<?php echo $cnt?>" value="<?=$pizzaID?>,<?=$pizzaName?>,<?=$pizzaPrice?>" placeholder = "0"/>
    <?php }
    

    当你读入 POST 值时,每个命名数组的格式为key =&gt; [id =&gt; value]

    然后您可以使用 id 键字符串来统一使用 array_merge_recursive 的 2 个数组中的值。

    $q = $_POST['Quantities'] ?? [];
    $c = $_POST['CheckBox'] ?? [];
    $merged = array_merge_recursive($q, $c);
    

    这将组合与每个pizzaId 键关联的所有值。结果数组如下所示:

    Array
    (
        [id_1] => Array
            (
                [0] => 1,Hawaiian,150
                [1] => 23
            )
    
        [id_3] => Array
            (
                [0] => 3,Four Cheese,300
                [1] => 33
            )
    )
    

    现在您可以压缩这些合并的数组,为每个 PizzaId 生成一个逗号分隔的列表:

    $squashed = array_map(function($v){ 
        return is_array($v) 
            ? implode(',', $v) 
            : $v; 
    }, $merged);
    
    

    $squashed 数组现在将包含:

    Array
    (
        [id_1] => 1,Hawaiian,150,23
        [id_3] => 3,Four Cheese,300,33
    )
    

    如果需要,可以从键中删除 id_ 前缀。

    需要注意的是,如果用户只提交了 2 个输入字段中的 一个 的值,则结果数组将仅包含该单个值,并且需要进一步分析以确定这是否是 QuantityCheckbox 值(例如检查 is_int() 可以确定该值是否属于 Quantity)。

    【讨论】:

    • 这是一个很好的答案。它仍然受到我在另一条评论中描述的前端 UX 缺陷的影响——如果用户输入数量但忘记选中复选框(反之亦然),一切都会中断。我会删除该复选框 - 您拥有Quantities 数组的 ID 和数量,并且无论如何您都不能相信来自浏览器的价格。您可以根据 POSTed ID 查找价格。
    • 你是对的@Don'tPanic - 正如你在回答中所描述的那样,更好的解决方案是排除已知的业务数据并完全不需要复选框
    【解决方案3】:
    $values = array();
    $quantities = array();
    
    foreach($_POST['CheckBox'] as $key => $value){
        array_push($values, $value);
    }
    
    $quantities = $_POST['Quantities'];
    $i=0;
    
    foreach ($quantities as $q){
       if($q){
           $values[$i] = $values[$i].','.$q;
           $i++;
       }
    }
    

    下面是我的输出
    大批 ( [0] => 1,哈瓦,150,23 [1] => 3,四,300,33 )

    【讨论】:

    • 这行得通,但它依赖于非 0 的数量,对应的复选框被勾选。如果客户输入第 5 个数量,但忘记选中该框(反之亦然,勾选该框但忘记数量),则所有结果都关闭 - 不仅针对该披萨,还针对所有其他结果。这个答案有效,但它假设前端将始终发送精确匹配的数据 - 它不会。
    • 它适用于位值为十的数量,但当数量为数百及以上或只有一位数(位值为一)时,它返回 0。
    【解决方案4】:

    这里您的复选框数组索引与数量索引不同,因此您必须更改代码方式:

    在单击复选框时,您必须将数量与复选框值结合起来,例如:

    $(document).on('click','input[name=checkBoxName]',function()
    {
      if($(this).is(":checked")) //check if checkbox checked
      {
        var key = $(this).attr('data-cnt');
        var qty = $("#qty"+key).val(); //return qty id value like qty1
        $(this).val($(this).val()+','+qty);
      }
      else //check box not checked then remove last qty value
      {
        var text = $(this).val(); 
        var resArray = text.split(",");
        var poppedItem = resArray.pop();
        var result = resArray.toString();
        $(this).val(result);
      }
    });
    

    在while循环之前声明cnt=0;

    while()
    {?>
      <input type = "number" name = "Quantities[]" id="qty<?php echo $cnt?>" placeholder = "0"/>
      <input type = "checkbox" name = "CheckBox[]" data-cnt="<?php echo $cnt?>" value="<?=$pizzaID?>,<?=$pizzaName?>,<?=$pizzaPrice?>" placeholder = "0"/>
    <?php }
    

    当您发布数据时,您将获得:

    foreach($_POST['CheckBox'] as $key => $value){
        array_push($values, $value);
    }
    
    var_dump($values);
    

    你会得到预期的输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-17
      • 1970-01-01
      • 2010-10-10
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      相关资源
      最近更新 更多