Reputation: 3
This has me stumped. print_r displays the correct array indices and values, but the foreach construct retrieves erroneous values and even changes the value for the last index even though I'm not retrieving the values by reference (not using the ampersand).
<?php
require './includes/dbal.php';
require './includes/user.php';
require './includes/book.php';
session_start();
$title='My Shopping Cart';
include './template/header.php';
if(!isset($_SESSION['user']))
{
die('You are not logged in.');
}
if(!isset($_SESSION['cart']))
{
$_SESSION['cart'] = array();
}
if(isset($_POST['submit']) && strcmp($_GET['mode'], 'add') == 0)
{
if(filter_var($_POST['qty'], FILTER_VALIDATE_INT) == FALSE)
{
echo '<div style="color: red;">Invalid quantity specified. Please go back and use a valid quantity.</div>';
}
else
{
$_SESSION['cart'][$_POST['book_id']] = $_POST['qty'];
}
}
else if(isset($_POST['update']) && strcmp($_GET['mode'], 'update') == 0)
{
foreach($_SESSION['cart'] as $key => &$value)
{
if((int) $_POST["qty_$key"] === 0)
{
unset($_SESSION['cart']["$key"]);
}
else
{
$value = $_POST["qty_$key"];
}
}
}
echo '<h3>Your shopping cart</h3>';
$db = new DBal();
$total=0;
echo '<div id="cart-items"><ul><form action="./cart.php?mode=update" method="post">';
// echo 'Original array: '; print_r($_SESSION['cart']);
foreach($_SESSION['cart'] as $key => $value)
{
// echo '<br />$key => $value for this iteration: ' . "$key => $value<br />";
// print_r($_SESSION['cart']);
$b = new Book($key, $db);
$book = $b->get_book_details();
$total += $value * $book['book_nprice']
?>
<li>
<div><img src="./images/books/thumbs/book-<?php echo $book['book_id']; ?>.jpg" title="<?php echo $book['book_name']; ?>" /></div>
<span class="cart-price">Amount: Rs. <?php echo $value * $book['book_nprice']; ?></span>
<h3><?php echo $book['book_name']; ?> by <?php echo $book['book_author']; ?></h3>
Price: Rs. <?php echo $book['book_nprice']; ?><br /><br />
Qty: <input type="number" name="qty_<?php echo $book['book_id']; ?>" maxlength="3" size="6" min="1" max="100" value="<?php echo $value; ?>" /><br />
</li>
<?php } echo "<span class=\"cart-price\">Total amount: $total</span>" ?>
<br />
<input type="submit" name="update" value="Update Cart" />
</form></ul></div>
<?php include './template/footer.html'; ?>
Sample output after pressing the update button is like this :
Original array:
Array (
[9] => 6
[8] => 7
[3] => 8
)
$key => $value for this iteration: 9 => 6
Array (
[9] => 6
[8] => 7
[3] => 6
)
$key => $value for this iteration: 8 => 7
Array (
[9] => 6
[8] => 7
[3] => 7
)
$key => $value for this iteration: 3 => 7
Array (
[9] => 6
[8] => 7
[3] => 7
)
The value for the last index gets changes to the value of the current index in every iteration. This results in the last value output having the same value as the second-to-last index.
Help?
Upvotes: 0
Views: 121
Reputation: 455052
You are using references here:
foreach($_SESSION['cart'] as $key => &$value)
Either don't use reference here or unset $value immediately after the loop.
Upvotes: 0
Reputation: 522109
You were using &$value
as reference before:
foreach($_SESSION['cart'] as $key => &$value)
The variable continues to exist as reference beyond the loop, using it again in a loop has expected but non-obvious side effects. This is even mentioned in a big red box in the manual. unset($value)
after the first loop to avoid that.
Upvotes: 3