1

I am learning some PHP and I am trying to create a all in one page shopping cart.

I have read into and can see the benefits of a SQL bases system, but I want to learn the basics first. In doing so I have create a all-in-one page that contains the products in an associated array, as well as a form that submits to itself.

What I want to achieve is:

  • A product can only be purchased once (buy button replaced with a remove button)
  • The item and its cost are added to the cart below
  • A user can either remove it from the cart, or the item list
  • The total cost should be updated as required.
  • The "checkout" button will submit item name and cost
  • The form posts to itself and does not require any SQL

My current problem is:

  • I cannot purchase more than one item at a time, i.e. the cart only contains the last purchased item
  • I cannot get it to "check" if an item has been purchased and if so, replace the "buy" with "remove"
  • I cannot display the item details in the cart
  • The checkout button does not pass any details to my test

Again, I am not looking for a SQL solution yet, just a pure PHP using $_SESSION and $_POST and would like to use buttons instead of <a href add?> type links.

Thanks for the lengthy read in advance here is the code:

<?php
session_start ();

$items = array (
        'A123' => array (
                'name' => 'Item1',
                'desc' => 'Item 1 description...',
                'price' => 1000 
        ),
        'B456' => array (
                'name' => 'Item40',
                'desc' => 'Item40 description...',
                'price' => 2500 
        ),
        'Z999' => array (
                'name' => 'Item999',
                'desc' => 'Item999 description...',
                'price' => 9999 
        ) 
);

if (! isset ( $_SESSION ['cart'] )) {
    $_SESSION ['cart'] = array ();
}

// Add
if (isset ( $_POST ["buy"] )) {
    $_SESSION ['cart'] = $_POST;
} 

// Delete Item
else if (isset ( $_POST ['delete'] )) { // a remove button has been clicked
    unset ( $_POST ['delete'] ); //
} 

// Empty Cart
else if (isset ( $_POST ["delete"] )) { // remove item from cart
    unset ( $_SESSION ['cart'] );
}

?>
<form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'>
    <?php
        foreach ( $items as $ino => $item ) {
            $title = $item ['name'];
            $desc = $item ['desc'];
            $price = $item ['price'];

            echo " <p>$title</p>";
            echo " <p>$desc</p>";
            echo "<p>\$$price</p>";

            if ($_SESSION ['cart'] == $ino) {
                echo '<img src="carticon.png">';
                echo "<p><button type='submit' name='delete' value='$ino'>Remove</button></p>";
            } else {
                echo "<button type='submit' name='buy' value='$ino'>Buy</button> ";
            }
        }
    ?>
</form>

<?php
if (isset ( $_SESSION ["cart"] )) {
    ?>

<form action='(omitted link)'
target='_blank' method='post'
enctype='application/x-www-form-urlencoded'>
<table>
    <tr>
        <th>Product</th>
        <th>Price</th>
        <th>Action</th>
    </tr>
    <?php

    $total = 0;
    foreach ( $_SESSION ["cart"] as $i ) {
        ?>
    <tr>
        <td>
            <?php echo($_SESSION["cart"]); ?> <!--Item name-->
        </td>
        <td>price<?php echo($_SESSION["price"][$i] ); ?>
            <!--Item cost-->
        </td>
        <td><button type='submit' name='delete' value='$ino'>Remove</button>
            </p></td>
    </tr>
    <?php
        $total = + $_SESSION ["amounts"] [$i];
    }
    $_SESSION ["total"] = $total;
    ?>
    <tr>
        <td colspan="2">Total: $<?php echo($total); ?></td>
        <td><input type='submit' value='Checkout' /></td>
    </tr>
    <tr>
        <td><button type='submit' name='clear'>Clear cart</button></td>
    </tr>
</table>
</form>
<?php  } ?>
3
  • You keep overwriting your cart contents on this line $_SESSION ['cart'] = $_POST; You need to merge the current session with the $_POST array. Commented Feb 1, 2017 at 7:05
  • You aren't using php to echo here: value='$ino', you will need value='<?php echo $ino ?>' although I don't see where you set $ino. Maybe I am just missing it. I only see it in the loop above that one...which won't work as intended in that loop. Commented Feb 1, 2017 at 7:06
  • 2
    I've added an answer which breaks down the various updates required. Please let me know if I've missed anything or you'd like further clarifications. Commented Feb 1, 2017 at 7:40

1 Answer 1

3

There's a few things that need fixing in your script, so I'll break them down into their individual parts.

There's a lot of security error checks that should also be done with the code, but as a pure learning exercise, I'm bypassing those factors.

Defining the cart

You're defining the shopping cart as an array:

if (! isset ( $_SESSION ['cart'] )) {
    $_SESSION ['cart'] = array ();
}

However, when you add an item to the cart, you're replacing the cart:

// Add
if (isset ( $_POST ["buy"] )) {
    $_SESSION ['cart'] = $_POST; // 
} 

To add an item to the cart, you should be using $cart[] = $_POST, but, there are additional things to take into account.

Adding to cart

The $cart[] = $_POST adds the full $_POST data to the cart, when you only need the product ID. The correct way would be:

// Add
if (isset ( $_POST ["buy"] )) {
    // Check the item is not already in the cart
    if (!in_array($_POST ["buy"], $_SESSION['cart'])) {
        // Add new item to cart
        $_SESSION ['cart'][] = $_POST["buy"];
    }
}

This would result in the cart storing multiple values. For example, a print_r($_SESSION['cart']) might show:

array (
    0 => 'A123',
    1 => 'B456'
);

Each item in this array would be an item that has been added to your cart.

Removing an item from your cart

Now that the structure of $_SESSION['cart'] has been changed, the "remove from cart" action requires updates too. Using a little snippet of code, we can check if the value exists in the array, find its key, and remove it.

// Delete Item
else if (isset ( $_POST ['delete'] )) { // a remove button has been clicked
    // Remove the item from the cart
    if (false !== $key = array_search($_POST['delete'], $_SESSION['cart'])) {
        unset($_SESSION['cart'][$key]);
    }
}

Check if the item is in your cart

Further changes to your code would be required to support the new array structure. You can use in_array to check if your product is contained in the cart array.

<?php
    foreach ( $items as $ino => $item ) {
        // ... snipped for brevity

        // Check if an item is in the cart by checking for the existence of its ID:
        if (in_array($ino, $_SESSION['cart'])) { // The $ino would be 'a123' for your first product
            echo "<p><button type='submit' name='delete' value='$ino'>Remove</button></p>";
        } else {
            echo "<button type='submit' name='buy' value='$ino'>Buy</button> ";
        }
    }
?>

Simplifying your code

In the above code, I've removed some of the code. You are doing the following:

$title = $item ['name'];
$desc = $item ['desc'];
$price = $item ['price'];

echo " <p>$title</p>";
echo " <p>$desc</p>";
echo "<p>\$$price</p>";

This can be simplified to:

echo "<p>$item['name']</p>";
echo "<p>$item['desc']</p>";
echo "<p>\$$item['price']</p>";

Rather than the double $$ in the last line, I personally would use:

echo '<p>$' . number_format($item['name']) . '</p>';

This allows you to format the display of the number easier. Alternatively, you could use money_format.

Displaying the shopping cart

There are a few problems with this code.

  1. You're attempting to echo($_SESSION['cart']) which won't work. You cannot echo an array
  2. You're using foreach ($_SESSION ["cart"] as $i) incorrectly when attempting to display the values using <?php echo($_SESSION["price"][$i] ); ?>
  3. You're complicating the code used for the $total value
  4. The HTML isn't valid due to a random </p> thrown into the mix

The correct way to display this would be:

<?php
// Set a default total
$total = 0;
foreach ( $_SESSION['cart'] as $ino ) {
    ?>
<tr>
    <td>
        Name: <?php echo $items[$ino]['name']; ?>
    </td>
    <td>
        Price: <?php echo $items[$ino]["price"]; ?>
    </td>
    <td>
        <button type='submit' name='delete' value='<?php echo $ino; ?>'>Remove</button>
    </td>
</tr>
<?php
    $total += $items[$ino]['price'];
} // end foreach
?>

Total: $<?php echo $total; ?>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much for the help @Kirk Beard explaining how/why things are wrong is so much better than just providing a solution. I really appreciate the effort! Thanks again!
@Ben No worries :) You've put in the effort to learn, so I'm more than happy to put in the effort to help you along the way. Good luck with it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.