0
<tr align="center">
    <td>
        <input type="checkbox" name="remove[]" value="<?php echo $pro_id;?>">//removes checked items  
    </td>
    <td>
      <img src="admin_area/product_images/<?php echo $product_image?>" width="60" height="60"/><br>//displays products image
      <?php echo $product_title ?>//displays products title
  </td>
  <td>
      <input type="text" size="4" name="qty" value="<?php echo $_SESSION["qty"]; ?>"><span style="color:red">Required</span>
  </td>//textbox where user enters the new quantity
  <input type="hidden" name="pro_id" value="<?php echo $pro_id; ?>">
</td>
<?php
$sql = "select * from cart";
$run_query = mysqli_query($con,$sql);
while ($row = mysqli_fetch_array($run_query)) {
    $_SESSION["qty"] = $row['qty'];
}

if (isset($_POST['update_cart'])) {
    $ip = getIp();
    $Updateqty = $_POST['qty'];
    //get quantity from the text boxes which are repeated with every product

    $pro_id = $_POST['pro_id'];
    //gets the id from the hidden field

    $update_qty = "UPDATE cart SET qty='$Updateqty' where p_id='$pro_id' and ip_add='$ip'";
    $run_qty = mysqli_query($con, $update_qty);

    if ($run_qty) {
        echo"<script>window.open('cart.php','_self')</script>";
    }
}
?>
</tr>
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
White Hat
  • 9
  • 1
  • 1
    There doesn't appear to be anything wrong with your code. Are you sure `$pro_id` and `$ip` are set properly? – Jay Blanchard Jul 01 '16 at 16:25
  • 2
    [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)*** Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! – Jay Blanchard Jul 01 '16 at 16:26
  • You have to have `session_start();` at the top of all pages using sessions, is it in place? – Jay Blanchard Jul 01 '16 at 16:33
  • @Jay Blanchard yes the ip is a function i made for getting user ip addresses, and i have a session started as well – White Hat Jul 01 '16 at 17:28

1 Answers1

1

There's a problem here:

$sql = "select * from cart";
$run_query = mysqli_query($con,$sql);
while ($row = mysqli_fetch_array($run_query)) {
    $_SESSION["qty"] = $row['qty'];
}

This while loop will overwrite $_SESSION["qty"] with each iteration, so it will always be set to the quantity of the last item in the cart.

Then that session value is used in the display for each item.

<input type="text" size="4" name="qty" value="<?php echo $_SESSION["qty"]; ?>"><span style="color:red">Required</span>

Also, if what you've shown in your question is one row from a table that has multiple rows, and you have wrapped the entire table in one form, every input will be submitted, and since you have multiple values for qty and pro_id, only the last one will be used. This is what is making it look like every quantity is being updated.


I would suggest an approach like this to get it working. This may not work for you as-is, because I guessed on some of the names, but should be enough to show what I have in mind:

<?php

if (isset($_POST['update_cart'])) {
    $ip = getIp();

    // prepare an update statement
    $sql = "UPDATE cart SET qty=? where p_id=? and ip_add=?";
    $stmt = mysqli_prepare($con, $sql);

    // loop over each quantity and update
    foreach ($_POST['qty'] as $pro_id => $qty) {
        $stmt->bind_param("iis", $qty, $pro_id, $ip);
        $stmt->execute();
    }
}

$sql = "select * from cart";
$run_query = mysqli_query($con,$sql);
while ($row = mysqli_fetch_array($run_query)) {
    // update the session with the new values
    $_SESSION[$row['p_id']]['qty'] = $row['qty'];
}

?>

That should update quantity for each item, but it depends on an array of qty values being provided by your form. In order to have that, you need to name your inputs using an array syntax like this:

<form action="" method="post">
    <table>
        <?php foreach ($products as $product): ?>
        <tr>
            <td>Other product info</td>
            <td>
                <input type="text" 
                    name="qty[<?php echo $product['id'] ?>]"
                    value="<?php echo $_SESSION[$product['id']]['qty']; ?>">
            </td>
        </tr>            
        <?php endforeach ?>
    </table>
    <input type="submit" name="update_cart" value="Update Cart">
</form>
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • The UPDATE query isn't in the while loop and the OP is using a different variable in the UPDATE: `$Updateqty=$_POST['qty'];` But *yikes* I do see where the logic is screwed up. – Jay Blanchard Jul 01 '16 at 16:41
  • @JayBlanchard There's no form in the question code, which implies that there's one form wrapping multiple instances of the tr that they've shown. So I think it looks like they have a lot of different instances of `qty` and `pro_id`, and they'll always get the last one. – Don't Panic Jul 01 '16 at 16:43
  • Oh, and I just noticed that the closing tr is after the PHP code, so it might be repeated as well. – Don't Panic Jul 01 '16 at 16:45
  • Yeah, it looks a mess from here for sure. – Jay Blanchard Jul 01 '16 at 16:45
  • You re correct the last row in the table is the only one updating, how can i escape that, i need to update a specific value for each row, also the whole thing is wrapped in one form – White Hat Jul 01 '16 at 17:30
  • @ImadFarran I updated the answer with my suggestion for how to handle this. – Don't Panic Jul 01 '16 at 18:31
  • @Don'tPanic the update worked for each item, thanks ! but i still have a problem with displaying it from the database, first item always says "br />Notice: Undefined offset: 7 in C:\xampp\htdocs\Site\ecommerce\cart.php on line 108
    ", i used this to save the row in session: $_SESSION[$row['p_id']]['qty'] = $row['qty']; and to echo: echo $_SESSION[$pro_id]['qty'] //its on line 108
    – White Hat Jul 02 '16 at 11:40