简体   繁体   English

PHP foreach() 仅输出数组的最后一项

[英]PHP foreach() outputs only the last item of an array

Sequel to my previous post, my intention was only to keep my question straight to the point and short, but obviously and for the sake of clarity, it's best I include all the modules involved.作为我上一篇文章的续集,我的目的只是让我的问题直截了当且简短,但显然,为了清楚起见,最好包括所有涉及的模块。

I'm working on a CodeIgniter project that requires users to provide multiple options with the help of an input post array like the one shown in the view below:我正在开发一个 CodeIgniter 项目,该项目要求用户在输入后数组的帮助下提供多个选项,如下图所示:

<form action="javascript:void(0)" id="add_stock">
   <div class="stock">
      <div>
         <div class="form-group col-md-4">
           <input type="text" name="item[]" placeholder="Name of item" class="form-control item" id="item" />
           <span class="item_err"></span>
         </div>
         <div class="form-group col-md-4">
           <input type="text" name="unit[]" list="units" placeholder="Enter unit of measurement" class="form-control unit" id="unit" />
           <datalist id="units">
              <option>cube</option>
              <option>cup</option>
           </datalist>
           <span class="unit_err"></span>
         </div>
         <div class="form-group col-md-3">
            <input type="text" onfocus="(this.type='number')"  name="quantity[]" placeholder="Enter quantity" class="form-control quantity" id="quantity" />
            <span class="quantity_err"></span>
          </div>
          <div class="form-group col-md-1">
             <button class="btn btn-primary add-more-stock" title="Add more item" style ="height:33px;margin-top: ;"><i class="fa fa-plus"></i></button>
          </div>
          <div class="clearfix"></div>
       </div>
     </div>
     <div class="clearfix"></div>
     <div class="form-group msg"></div>
     <div class="form-group col-md-12">
       <button class="btn btn-primary add-stock text-uppercase"><i class="fa fa-plus"></i> add stock</button>
     </div>
 </form>

I have a jQuery code that appends additional input fields as shown below:我有一个 jQuery 代码,它附加了额外的输入字段,如下所示:

    var max_fields = 20; // maximun inputs allowed
    var items = $('.stock');
    var x = 1;
    $('.add-more-stock').click(function (e) {
      e.preventDefault();
      if (x < max_fields) {
        x++;
        $('.stock').append('<div><div class="form-group col-md-4"><input type="text" name="item[]" placeholder="Name of item" class="form-control item" id="item" /><span class="item_err"></span></div><div class="form-group col-md-4"><input type="text" name="unit[]" list="units" placeholder="Enter unit of measurement" class="form-control unit" id="unit" /><datalist id="units"><option>cube</option><option>cup</option><option>mudu</option><option>bags</option><option>carton</option> <option>crate</option> <option>bottle</option></datalist><span class="unit_err"></span></div><div class="form-group col-md-3"><input type="text" name="quantity[]" placeholder="Enter quantity" class="form-control quantity" id="quantity" /> <span class="quantity_err"></span></div><button class="btn btn-danger remove-stock col-sm-1" title="Remove item" style ="height:33px;margin-bottom: -1px; width: 40px;"><i class="fa fa-trash"></i></button></div>');
      }else{
        $('.input-alert').attr('class','alert alert-warning').html('<i class="fa fa-info-circle"></i> You have reached the maximun of 20 input fields reached.').show();
      }
    })

    
    $(items).on('click','.remove-stock',function (e) {
      e.preventDefault();
      $(this).parent('div').remove();
      $('.input-alert').hide();
    })

And here is the complete jQuery code that passes the contents of the text fields to my controller:这是完整的 jQuery 代码,它将文本字段的内容传递给我的 controller:

   $('.add-stock').click(function (e) {

      var item = new Array();
      var unit = new Array();
      var quantity = new Array();

      var item_arr = $("input[name^='item']");

      var unit_arr = $("input[name^='unit']");

      var quantity_arr = $("input[name^='quantity']");

      item_arr.each(function(){
        item.push(this.value);
      }); 

      unit_arr.each(function(){
        unit.push(this.value);
      }); 

      quantity_arr.each(function(){
        quantity.push(this.value);
      });

      $.ajax({
        url: '<?php echo base_url()?>admin/add_stock',
        type: 'post',
        data: {item:item,unit:unit,quantity:quantity},
        dataType: 'json',
        beforeSend: function () {
          $(".add-stock").html("<img src='<?php echo base_url()?>asset/images/a.gif' width='20' height='20'/> proceesing...");
        },
        success: function (data) {
          if (data.success) {
            $('.add-stock').html('<i class="fa fa-plus"></> add stock');
            $('.msg').attr('class', 'alert alert-success').html('<i class="fa fa-check"></> '+data.msg).delay(5000).fadeOut();
          }else if (data.error) {
            if (data.unit) {
              $('.add-stock').html('<i class="fa fa-plus"></> add stock');
              $('.unit_err').attr('class', 'text-danger').html(data.unit).delay(5000).fadeOut();
            }else if (data.item) {
              $('.add-stock').html('<i class="fa fa-plus"></> add stock');
              $('.item_err').attr('class', 'text-danger').html(data.item).delay(5000).fadeOut();
            }else if (data.quantity) {
              $('.add-stock').html('<i class="fa fa-plus"></> add stock');
              $('.quantity_err').attr('class', 'text-danger').html(data.quantity).delay(5000).fadeOut();
            }else if (data.failed) {
              $('.add-stock').html('<i class="fa fa-plus"></> add stock');
              $('.msg').attr('class', 'alert alert-danger').html('<i class="fa fa-times"></> could not procees request...').delay(5000).fadeOut();
            }
          }
        },
        error: function () {
          $('add-stock').html('<i class="fa fa-plus"></> add stock');
          $('.msg').attr('class', 'alert alert-warning').html('<i class="fa fa-warning"></> something went wrong.').delay(5000).fadeOut();
        }
      })
    })

So, am trying to get the options in order to store them in separate rows and respective columns with the help of PHP (CodeIgniter)...因此,我试图在 PHP(CodeIgniter)的帮助下获取选项,以便将它们存储在单独的行和相应的列中......

So far, this is my full controller到目前为止,这是我完整的 controller

    function add_stock()
    {
        
            $items = $_POST['item'];
            $units = $_POST['unit'];
            $quantitys = $_POST['quantity'];

            foreach ($items as $item) {
                $stock['item'] = $item;
            }

            foreach ($units as $unit) {
                $stock['unit_of_measurement'] = $unit;
            }

            foreach ($quantitys as $quantity) {
                $stock['quantity'] = $quantity;
            }
            $stock['added_by'] = 'Admin';
            
            
            $stmt = $this->db->insert('stocks', $stock);

            if($stmt):
                $array = array('success' => true, 'msg'=>'Item has been successfully added to store');
            else:
                $array = array('error' => true, 'failed'=>true);
            endif;
        echo json_encode($array);
    }

Now, the problem is that, instead of getting the whole contents of the array displayed, only the last content is outputted ie if the contents of $array are ['a','b'], instead of displaying a,b the foreach() loop only displays b.现在,问题在于,不是显示数组的全部内容,而是只输出最后一个内容,即如果 $array 的内容是 ['a','b'],而不是显示 a,b foreach () 循环只显示 b。

But when I echo $items, $units or $quantitys itself, the contents of the array gets displayed.但是当我回显 $items、$units 或 $quantitys 本身时,会显示数组的内容。

So, please, how can I get all the contents of the array and insert them into different rows?那么,请问如何获取数组的所有内容并将它们插入不同的行?

Thank you!谢谢!

Your problem starts in your form, and then gets worse in your controller.您的问题从您的表单开始,然后在您的 controller 中变得更糟。

The specific issue in your controller is this:您的 controller 中的具体问题是这样的:

foreach ($items as $item) {
   $stock['item'] = $item;
}

You're iterating over the $items array, but overwriting the value of $stock['item'] on each iteration.您正在迭代$items数组,但在每次迭代时覆盖$stock['item']的值。 Only the last value is stored.仅存储最后一个值。

To fix this you need to do a number of things:要解决此问题,您需要做很多事情:

First, use array indexes in your form names.首先,在表单名称中使用数组索引。 This allows you to extract the corresponding values in the arrays you receive in $_POST这允许您提取在$_POST中收到的 arrays 中的相应值

In your HTML use name="item[0]" , name="unit[0]" , name="quantity[0]" in your <input> fields.在您的 HTML 中,在您的<input>字段中使用name="item[0]" , name="unit[0]" , name="quantity[0]"

Then, in the Javascript code that adds new rows, increment the index for each new row.然后,在添加新行的 Javascript 代码中,为每个新行增加索引。 You already have a counter that you can use for this = x .您已经有一个可以用于 this = x的计数器。

'<input type="text" name="item[' + x + ']" placeholder="Name of item" class="form-control item" id="item" />'

(I haven't reproduced the whole line - you get the idea) (我没有复制整行 - 你明白了)

These changes should give you three arrays in your input that you can iterate over in a single loop:这些更改应该在您的输入中为您提供三个 arrays ,您可以在单个循环中进行迭代:

$items = $_POST['item'];
$units = $_POST['unit'];
$qtys = $_POST['quantity'];

for($i=0;$i<count($items); $i++) {
    $item = $items[$i];
    $unit = $units[$i];
    $qty = $qtys[$i];

    // Do your database update here with these three variables

} }

Purists will note that you could use the array elements directly.纯粹主义者会注意到您可以直接使用数组元素。 I agree, but this is clearer.我同意,但这更清楚。

You could extend the indexes to give you a two dimensional array:您可以扩展索引以提供二维数组:

name="products[0]['item']" 
name="products[0]['unit']"
name="products[0]['quantity']"

(and corresponding changes to use x in Javascript) (以及在 Javascript 中使用x的相应更改)

Then iterate over $_POST]['products']:然后遍历 $_POST]['products']:

foreach($_POST['products'] as $product) {
     $unit = $product['unit'];
     ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM