Reputation: 305
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:
My current problem is:
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 } ?>
Upvotes: 1
Views: 5377
Reputation: 9843
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.
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.
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.
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]);
}
}
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> ";
}
}
?>
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
.
There are a few problems with this code.
echo($_SESSION['cart'])
which won't work. You cannot echo
an arrayforeach ($_SESSION ["cart"] as $i)
incorrectly when attempting to display the values using <?php echo($_SESSION["price"][$i] ); ?>
$total
value</p>
thrown into the mixThe 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; ?>
Upvotes: 3