basic arrays from form

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

basic arrays from form

Post by paul00 »

hello people

First post here so please be nice :p I'm pretty advanced in php and html but there's one area i haven't used allot and that's arrays and im confused.

Iv made a shopping cart in php with a class, and now im working on editing a carts qty from a form. So each item in cart can have there qtys updated at the same time, only way i can think doing this is in a array.

Is it possible you good people can give me a basic example to play with?

Little more details

All cart contents are stored in sessions. Each item has..

$id = Product id
$qty = Product qty (default is 1)
$desc = Product description
$price = Price

In the update form i only have qty that is changeable, so if a user adds a item, but wants 4 of them, this can be updated in the shopping cart, and he/she may update other items at the same time.

The problem im haven is when i use a foreach statement it is overwriting the last value. I need both $id and $qty to pass though to call this function

$cart->edit_item( $id, $qty );

But i need to do them all at the same time, hence the loop

Hope someone can help me, and that i haven't confused anyone more than iv confused my self

Many thanks
Paul
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

Thought id add my HTML form so people can see what im trying to pass onto php to update. Remember there could be 10 items, and all qtys could be changed at one time. part of this html has while function on it to loop a row per item ;)

Code: Select all

 
<form name="form1" method="post" action="">
      <table class="cart" width="100%">
        <tr>
          <td class="cart" width="12%">Code</td>
          <td class="cart" width="9%">Qty</td>
          <td class="cart" width="64%">Description</td>
          <td class="cart" width="10%">Price</td>
          <td class="cart" width="5%"><div align="center">Remove</div></td>
        </tr>
[b](LOOP START)[/b]     
  <tr>
          <td class="cartrow"><span>'. $item['id']. '
            <input name="id" type="hidden" id="id" value="'. $item['id']. '">
          </span></td>
          <td class="cartrow"><input name="qty" type="text" id="qty" value="'. $item['qty']. '" size="5" maxlength="5"></td>
          <td class="cartrow"><span>'. $item['info']. '</span></td>
          <td class="cartrow"><span>'. $item['subtotal']. '</span></td>
          <td class="cartrow"><div align="center"><a href="removeitem.php?id='. $item['id'] .'">X</a></div></td>
        </tr>
[b](LOOP FINISH)[/b]    
     </table>
          <div align="right">
            <input type="submit" name="Submit" value="Update Total">
            <br>
        </div>
    </form>
 
So now i need a explain of how i can take each row edited and update there qtys.

Each row has $id and $qty vars.

Editing item is called with $cart->edit_item( $id, $qty );

Paul
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

Anyone got any ideas?
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

well i give up lol

been trying to figure thi out fr hours.

Code: Select all

 
foreach ($_POST as $key => $value) {
    if (is_array($value)) {
      foreach ($value as $subkey => $subvalue) {
        echo "$subkey: $subvalue\n<br>";
      }
    } 
 
}
 
Iv been playing with that code and got all the _POST items echo'd out but there out of order. The above gives the following output;

Code: Select all

0: maaf-1 
1: max-2-ply_80/100-21 
0: 1 
1: 1
I need it to display

Code: Select all

 
0: maaf-1 
1:  1
0: max-2-ply_80/100-21 
1: 1
 
I think :s

Totaly confused!
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

Anyone with any suggestions at all? Im starting to think this cant be done this way??

Cheers
Paul
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: basic arrays from form

Post by thinsoldier »

ok on line 14 I see where you have the id of the item as a hidden field but you're not providing a name="" on the input so your code after submitting the form won't actually know what item ID that submitted quantity value is associated with.

Also, if you have 5 items in the cart that loop will produce 5 inputs named "quantity" and 5 hidden inputs with no name="" yet a value of $item['id'] so your assumption of "Each row has $id and $qty vars." won't be true when you submit the form for 2 reasons.

1. lack of name attribute on the hidden inputs means no $_POST['id'] --*whoops, you did have name in there***
2. [input name="qty" value="$item['id']"] - even with 5 such fields only the last one on the page will actually have it's value submitted. Each $qty is overwritten by the next $qty in the form. To get multiple values submitted under the variable named $qty you need to name the form input as an array.
[input name="qty[]" value=$item[$id]]

With your field named this way $_POST will contain 1 [qty] entry that is an array with 5 values in it

And an easier way to see the contents of post is just print_r($_POST). I usually wrap that in a <pre> to avoid having to view source to see it nicely laid out. Then I wrap that in a function called preprintr
Warning: I have no idea what I'm talking about.
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: basic arrays from form

Post by thinsoldier »

*** EDITED MULTIPLE TIMES IN THE LAST 5 MINUTES [2008-12-21 10:23 pm]***

Code: Select all

 <? // warning: pseudocode - copy/paste will NOT work
 
$htmlform = '<form name="form1" method="post" action="'.thispage().'">';
 
foreach($_SESSION['shoppingcart'] as $item)
{
$item = (object) $item; // cuz i prefer the -> syntax :)
 
$htmlform .= <<<HEREDOC
<label>code</label><span>$item->id</span>
 
<input name="id[]" type="hidden" value="'. $item->id. '">
<label>quantity</label>
<input name="qty[]" type="text" value="$item->qty" />
 
<label>description</label>
....
<label>price</label>
......
<label>remove</label>
.....
HEREDOC;
}
 
echo $htmlform . '</form>';
?>
 
 
<?
// after sumbitting
print_r($_POST);
foreach($_POST['id'] as $key => $unimportant )
{
    echo "item id: $_POST[id][$key] -- new quantity: $_POST[qty][$key] <br />";
}
?>
 
Last edited by thinsoldier on Sun Dec 21, 2008 9:23 pm, edited 4 times in total.
Warning: I have no idea what I'm talking about.
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

thinsoldier wrote:ok on line 14 I see where you have the id of the item as a hidden field but you're not providing a name="" on the input so your code after submitting the form won't actually know what item ID that submitted quantity value is associated with.

Also, if you have 5 items in the cart that loop will produce 5 inputs named "quantity" and 5 hidden inputs with no name="" yet a value of $item['id'] so your assumption of "Each row has $id and $qty vars." won't be true when you submit the form for 2 reasons.

1. lack of name attribute on the hidden inputs means no $_POST['id'] --*whoops, you did have name in there***
2. [input name="qty" value="$item['id']"] - even with 5 such fields only the last one on the page will actually have it's value submitted. Each $qty is overwritten by the next $qty in the form. To get multiple values submitted under the variable named $qty you need to name the form input as an array.
[input name="qty[]" value=$item[$id]]

With your field named this way $_POST will contain 1 [qty] entry that is an array with 5 values in it

And an easier way to see the contents of post is just print_r($_POST). I usually wrap that in a <pre> to avoid having to view source to see it nicely laid out. Then I wrap that in a function called preprintr
I see, Im still slighly unsure what you getting too. Do you have any examples?
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

wow, be late on my reply. lol Thanks

I will see what it gives. thanks for the example! :D
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

Hmmm dont work, if im doing it right....

This is my current code that dont work right but does a little, same problems i had, with one item haven the others value! wrong order :p

Code: Select all

 
<?PHP
//qty change
 
if (isset($_POST['Submit'])) {
 
    print_r($_POST);
    foreach($_POST['id'] as $key => $unimportant ) {
        echo "item id: ".$_POST[id][$key]." -- new quantity: ".$_POST[qty][$key]." <br />";
    }
 
}
 
 
 
 
$items = $cart->get_contents();
$content .= '
<h1>Shopping Cart </h1>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td><form name="form1" method="post" action="viewcart.php">
      <table class="cart" width="100%">
        <tr>
          <td class="cart" width="12%">Code</td>
          <td class="cart" width="9%">Qty</td>
          <td class="cart" width="64%">Description</td>
          <td class="cart" width="10%">Price</td>
          <td class="cart" width="5%"><div align="center">Remove</div></td>
        </tr>
      
    ';
    
if ($cart_count < "1") { // no items
        $content .= '
            <tr>
            <td class="cartrow" colspan="3"><span>There are no items in your cart</span></td>
            </tr>
        ';
 
} else { // with items in cart
 
    foreach($items as $item) {
 
        $content .= '
        <tr>
          <td class="cartrow"><span>'. $item['id']. '
          <input name="id[]" type="hidden" value="'. $item->id. '">
 
                        <input name="id[]" type="hidden" id="id[]" value="'. $item['id']. '">
                        </span></td>  
                        <td class="cartrow"><input name="qty[]" type="text" value="'. $item['qty'] .'" size="5" maxlength="5" /></td>
 
              
        <td class="cartrow"><span>'. $item['info']. '</span></td>
        <td class="cartrow"><span>'. $item['subtotal']. '</span></td>
        <td class="cartrow"><div align="center"><a href="removeitem.php?id='. $item['id'] .'">X</a></div></td>
        </tr>
      ';
    
     }
    
}
 
?>
 
We will call
max-2-ply_80/100-21 item 1 in cart with qty 1
max-2-ply_100/90-19 item 2 in cart with qty 1 (Last one)

I am changing max-2-ply_100/90-19 (Last one on html output!) to QTY 5 (Which you see in output)

This is my ouput...

Code: Select all

 
 
Array ( [id] => Array ( [0] => [1] => max-2-ply_80/100-21 [2] => [3] => max-2-ply_100/90-19 ) [qty] => Array ( [0] => 3 [1] => 5 ) [Submit] => Update Total ) item id: -- new quantity: 3 
item id: max-2-ply_80/100-21 -- new quantity: 5 
item id: -- new quantity: 
item id: max-2-ply_100/90-19 -- new quantity: 
 
 
This is wrong!
item id: max-2-ply_80/100-21 -- new quantity: 5

This cant be right. that is the wrong id! Should be max-2-ply_100/90-19 but its picking the first listed item in html as its partner. it should be the last one.
Apart from that, there is a missing value. I haven't forgotten to add it :p
But we can clearly see in the array dump that all the figures are there, but not in order lol or where i really need them to be. :D

Thanks for your help, hope you can help me a little more with this :p

Paul
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: basic arrays from form

Post by thinsoldier »

hmm... with only 2 items in the cart line 5 shouldn't even exist (item id: -- new quantity:)

Ok, I'm starting to see where the problem is.

#1 Don't just copy/paste and expect what I gave to work :p
#2 You had extra hidden inputs

This one you can copy/paste to a new file and test it. It should do exactly what you want. From there you should be able to figure out what to do with your own code.

Code: Select all

<?
error_reporting(E_ALL);
 
// after sumbitting
if (isset($_POST['Submit'])) 
{
    echo '<pre>'.print_r($_POST,1).'</pre>';
    foreach($_POST['id'] as $key => $unimportant )
    {
        echo "item id: {$_POST['id'][$key]} -- new quantity: {$_POST['qty'][$key]} <br />";
    }
}
 
 
 
// initial page
$cart = new shoppingcart;
$items = $cart->get_contents();
$cart_count = count($items);
 
$content = '<h1>Shopping Cart </h1>
 <table width="35%" border="0" cellspacing="0" cellpadding="0">
   <tr>
     <td>
     <form name="form1" method="post" action="paul.php">
       <table class="cart" width="100%">
         <tr>
           <td class="cart" width="12%">Code</td>
           <td class="cart" width="9%">Qty</td>
           <td class="cart" width="64%">Description</td>
           <td class="cart" width="10%">Price</td>
           <td class="cart" width="5%"><div align="center">Remove</div></td>
         </tr>';
 
if ($cart_count < "1") { // no items
        $content .= '
            <tr>
            <td class="cartrow" colspan="3"><span>There are no items in your cart</span></td>
            </tr>
        ';
 
} 
else 
{ // with items in cart
    foreach($items as $key  => $item) 
    {
        $item = (object) $item;
        
        if(@$_POST['qty'][$key]){ $qty2show = $_POST['qty'][$key]; }
        else {$qty2show = $item->qty; }
        
        $content .= '
        <tr>
            <td class="cartrow"><span>'. $item->id. '
            <input name="id[]" type="hidden" value="'. $item->id. '">
            </span></td>  
            <td class="cartrow"><input name="qty[]" type="text" value="'. $qty2show .'" size="5" maxlength="5" /></td>
    
                 
        <td class="cartrow"><span>'. $item->info. '</span></td>
        <td class="cartrow"><span>'. $item->subtotal. '</span></td>
        <td class="cartrow"><div align="center"><a href="removeitem.php?id='. $item->id .'">X</a></div></td>
        </tr> ';
    }
 
} // end else with items in cart
 
$content .= '</table> <input type="submit" name="Submit" value="Submit" /> </form>';
 
echo $content;
 
 
//-------------
// class stuff
//-------------
class shoppingcart
{
    function get_contents()
    {
        $items[] = array(
        'id'=>1,
        'info'=>'max-2-ply_80/100-21',
        'qty'=>'1',
        'subtotal'=>'$123'
        );
        
        $items[] = array(
        'id'=>2,
        'info'=>'max-2-ply_100/90-19',
        'qty'=>'1',
        'subtotal'=>'$456'
        );  
        return $items;
    }
}
?>

Personally I think you have a few too many tables in there. Complex nested tables + complex php if/else with long blocks of code+html in each == hard to follow/debug/update
Warning: I have no idea what I'm talking about.
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

Hi thanks for the reply

Im not sure what you mean by too complex :p I can read it ok and edit it fine. I did C+P the query for reading the array but i had to chop bits up to get it like it is now.

Im confused about the class bit you added? The cart details are already stored in a session.

Paul
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: basic arrays from form

Post by thinsoldier »

paul00 wrote:Hi thanks for the reply
Im confused about the class bit you added? The cart details are already stored in a session.
Paul
Just a placeholder to represent wherever the data is supposed to be coming from. I saw you had $cart->get_contents(); and wanted to give you something you could actually run locally and have it work so I put in a placeholder class for it so that $cart->get_contents(); wouldn't cause the script to die.

The important part is that you see how the form is written and see the expected results in $_POST when you submit the form.


OH, and the part # if (isset($_POST['Submit'])), you should probably add another check to that just to be safe.
Check that is_array($_POST[id]) and that count($_POST[id]) is equal to count($_POST[qty]) since the code relies on them being in pairs.
Last edited by thinsoldier on Mon Dec 22, 2008 7:56 am, edited 1 time in total.
Warning: I have no idea what I'm talking about.
paul00
Forum Newbie
Posts: 13
Joined: Sat Dec 20, 2008 2:54 pm

Re: basic arrays from form

Post by paul00 »

Well that works :D

I will tidy up what i got now and post it later. I have a few questions reading the $unimportant?

Code: Select all

   foreach($_POST['id'] as $key => $unimportant )
    {
        //echo "item id: {".$_POST['id'][$key]."} -- new quantity: {".$_POST['qty'][$key]."} <br />";
        $cart->edit_item($_POST['id'][$key],$_POST['qty'][$key]);
    }
whys the need for the unimportant bit? can it be wrote like foreach($_POST['id'] as $key) ?
Is it possible you can explain to me in dumbass terms how that foreach works :p


Paul
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: basic arrays from form

Post by thinsoldier »

paul00 wrote:

Code: Select all

   foreach($_POST['id'] as $key => $unimportant )
    {
        //echo "item id: {".$_POST['id'][$key]."} -- new quantity: {".$_POST['qty'][$key]."} <br />";
        $cart->edit_item($_POST['id'][$key],$_POST['qty'][$key]);
    }
whys the need for the unimportant bit? can it be wrote like foreach($_POST['id'] as $key) ?
Is it possible you can explain to me in dumbass terms how that foreach works :p
normally you'll see a foreach as:
foreach( $array as $key => $value);

In that case we only care about the $_POST['id'][ $key ] because there are an unknown number of item in the $_POST['id'] array.
We won't be using the $value (or $unimportant) because we need to use that $key value to access data in 2 different arrays, only one of which is part of the definition of the foreach. We could have used $unimportant (rename it to $value) and had $cart->edit_item($unimportant , $_POST['qty'][$key]); but I felt it was more understandable to show that we're using just the $key to make sure we access the same array key in both the [id] and [qty] sub arrays of $_POST
Warning: I have no idea what I'm talking about.
Post Reply