Jump to content

associative arrays, sessions, and shopping carts . . .


metazai

Recommended Posts

I've written a shopping cart before, but using a string and explode() and implode() . . . but I've become intrigued with the idea of using associative arrays to do it without having to explode stuff all the time. Of course, since I've never done it, I'm going strictly by the php manual and all the help I can get, which obviously isn't enough, because I'm missing some logical step.

 

For the moment, I'm assuming passing an id (all other info can be pulled up from the MySQL, after all), the quantity, and three, count 'em, three variable options -- to be saved as, for instance, color^blue, or size^XXL.

 

I can get it working fine if the purchaser wants to see that he bought 1 or 99  blue XXL shirts, but if he buys 1 blue XXL shirt and 2 red SM shirts, since the array is all hooked on the product id, it overwrites the last color and size.  Here's the code from where the submitted "add to cart" form submits to the php:

 

<?php session_start();
$product_id=$_REQUEST['product_id'];
$product_quantity=$_REQUEST['product_quantity'];
//test to see if all three of the option variables are being used, create $variable_option and add on to it accordingly if they are.
if (!empty($_REQUEST['variable_name1'])) {$variable_options=$variable_options.$_REQUEST['variable_name1']."^".$_REQUEST['variable_option1']."|:|";}
if (!empty($_REQUEST['variable_name2'])) {$variable_options=$variable_options.$_REQUEST['variable_name2']."^".$_REQUEST['variable_option2']."|:|";}
if (!empty($_REQUEST['variable_name3'])) {$variable_options=$variable_options.$_REQUEST['variable_name3']."^".$_REQUEST['variable_option3']."|:|";}
//set true-false counter
$i=0;
//see if this product id has been ordered before (if so, a session associative array will have been set)
if (isset($_SESSION['cart'][$product_id]['options'])) {
//read the array to see if it contains an identical $variable_option value so we can just increase the amount
foreach ($_SESSION['cart'][$product_id]['options'] as $testoption) {
if ($testoption == $variable_options) {
  $_SESSION['cart'][$product_id]['qty'] += $product_quantity;
  $i=1;}}} 
//if true-false counter has not been kicked on, assume that this is a new value for $variable_option, determine how many difffernt variable names have already been added and add one to that for the next array slot 
  if ($i!=1){ 
  $newoptionnumber=(count($_SESSION['cart'][$product_id]['options']) + 1);
  $_SESSION['cart'][$product_id]['qty'] += $product_quantity;
  $_SESSION['cart'][$product_id]['options'][$newoptionnumber] = $variable_options;}
//test the results
echo '<pre>';
  print_r($_SESSION['cart']);
  echo '</pre>';
  
?>

The foreach obviously doesn't seem to work as I expected, in fact I get an error message from it each time.  Therefore I haven't tested the bottom and am not even sure I can add a new value to an array in this fashion.

 

Questions?  Comments?  Help? 

 

Help!

 

You could structure the array as

$_SESSION['cart'][$product_id][] = array (
                 'size' => 'XXL',
                 'color' => 'blue',
                 'qty' => 99
                );

 

echo $_SESSION['cart'][$product_id][0]['qty'];                      // 99

So what happens when someone comes along and orders a different size, color and quantity?  Will it store another set of numbers or simply overwrite those in your example?

 

Additionally, the 'size' and 'color' fields themselves will be variable . . . on one page it might be size and color, on another it might be material (plastic, steel, wood)  or pattern (sparklies, diamons, none).

So size and color become option1, option2

 

<?php
session_start();
add_to_cart (123,'red', 'XXL', 5);          // order item 1
add_to_cart (123,'blue', 'SM', 10);         // order item 2
add_to_cart (456,'wood', 'oak', 20);        // order item 3
add_to_cart (456,'plastic', 'sparkle', 1);  // order item 4

function  add_to_cart ($product_id, $opt1, $opt2, $qty)
{
    $_SESSION['cart'][$product_id][] = array (
                 'opt1' => $opt1,
                 'opt2' => $opt2,
                 'qty' => $qty
                );
}

// view cart
echo '<pre>', print_r($_SESSION['cart'], true), '</pre>';
?>

 

 

Understood . . . and I appreciate the response.  I guess what I'm trying to determine now is what happens when someone orders 456, 'wood', 'oak', 20  AGAIN.  I'm having trouble understanding how to make sure that displays in the cart as 456, 'wood', 'oak' 40.  In other words, when the items  match, they should add up.  My initial code (cruder than yours, and many thanks for the ideas on simplifying it) used a foreach() to attempt to pull out identical items and add them together  . . . is that the right way to do it?  Why was the foreach() not working on that code?

Is there some kind of rule about using foreach with session associative arrays? I keep getting stuff like:

 

Warning: Illegal offset type

 

and

 

Warning: Invalid argument supplied for foreach()

 

My addtocart now looks like this, and seems to work fine:

 

 

<?php session_start();
$product_id=$_REQUEST['product_id'];
$product_quantity=$_REQUEST['product_quantity'];
$variable_option1=$_REQUEST['variable_option1'];
$variable_option2=$_REQUEST['variable_option2'];
$variable_option3=$_REQUEST['variable_option3'];
  
add_to_cart ($product_id,$variable_option1,$variable_option2,$variable_option3,$product_quantity); 

function  add_to_cart ($prodid, $opt1, $opt2, $opt3, $qty)
{
    $_SESSION['cart'][$prodid][] = array (
                 'option1' => $opt1,
                 'option2' => $opt2,
			 'option3' => $opt3,
                 'quantity' => $qty
                );
}
header("location: ../cart.php");
?>

But I'm struggling with pulling the data out, like in a shopping cart:

foreach ($_SESSION['cart'] as $prodid) {
foreach ($_SESSION['cart'][$prodid] as $prodentry) {
foreach ($_SESSION['cart'][$prodid][$prodentry]['quantity'] as $prodquant) {
$prodquantupdate=($prodquantupdate + $prodquant);}
}echo $prodid;
echo $prodquant;
}

try

<?php
session_start();

function  add_to_cart ($prodid, $opt1, $opt2, $opt3, $qty)
{
    $found=0;
    if (isset($_SESSION['cart'][$prodid]))
    {
        foreach ($_SESSION['cart'][$prodid] as $i => $order)
        {
            if ($order['option1']==$opt1 && $order['option2']==$opt2 && $order['option3']==$opt3)
            {
                $_SESSION['cart'][$prodid][$i]['quantity'] += $qty;
                $found=1;
                break;
            }
        }
    }
    
    if (!$found) 
    {
        $_SESSION['cart'][$prodid][] = array (
                 'option1' => $opt1,
                 'option2' => $opt2,
                 'option3' => $opt3,
                 'quantity' => $qty
                );
    }
}


add_to_cart('234', 'A', 'B', 'C', 20);
add_to_cart('234', 'A', 'B', 'C', 20);

echo '<pre>', print_r($_SESSION['cart'], true), '</pre>';
?>

PS Output the cart

 

add_to_cart('123', 'XXL', 'Red', 'Sleeveless', 30);
add_to_cart('123', 'SM', 'Blue', 'Sleeves', 10);
add_to_cart('234', 'A', 'B', 'C', 20);
add_to_cart('234', 'A', 'B', 'C', 20);
add_to_cart('234', 'A', 'B', 'DD', 20);

echo '<table border="1">';
$prev='';
foreach ($_SESSION['cart'] as $prodid => $prodorder)
{
    if ($prodid != $prev)
    {
        echo "<tr><th colspan='4'>Product: $prodid</th></tr>";
        $prev = $prodid;
    }
    foreach ($prodorder as $po)
    {
        echo "<tr>
                <td>{$po['option1']}</td>
                <td>{$po['option2']}</td>
                <td>{$po['option3']}</td>
                <td>{$po['quantity']}</td>
                </tr>"; 
    }
    
}
echo '</table>';

 

-->

<table border="1"><tr><th colspan='4'>Product: 123</th></tr>
<tr>
                <td>XXL</td>
                <td>Red</td>
                <td>Sleeveless</td>
                <td>30</td>
                </tr>
<tr>
                <td>SM</td>
                <td>Blue</td>
                <td>Sleeves</td>
                <td>10</td>
                </tr>
<tr><th colspan='4'>Product: 234</th></tr>
<tr>
                <td>A</td>
                <td>B</td>
                <td>C</td>
                <td>40</td>
                </tr>
<tr>
                <td>A</td>
                <td>B</td>
                <td>DD</td>
                <td>20</td>
                </tr>
</table>

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.