Hey guys,

I'm trying to update an existing site and I'm having a few issues with an array in terms of sorting the results of an array into a simple div layout. It currently works and the output is working fine. However I want to define a category as a parent.

<?php
$_SESSION['cart'] = array(0 => array(0 => "empty"));

$increment = count($_SESSION['cart']);

$_SESSION['cart'][$increment] = array("category" => $category,
                                      "product" => $product);

$increment = count($_SESSION['cart']) - 1;

for ($i = 1; $i <= $increment; $i++)
{
  echo "<div style=\"clear: both;\">" . $_SESSION['cart'][$i]['category'] . "</div>";
  echo "<div style=\"clear: both;\">" . $_SESSION['cart'][$i]['product'] . "</div>";
}
?>

This works, however I'm getting a repeat Category title for each loop. Where I would prefer the category to be a parent for many products that relate to the category.

Displayed like this perhaps?

Category
Product
Product

Category
Product
Product

Category
Product
Product

Any help would be great ... Thanks in advance.

I think you need to restructure your cart array:

<?php 

$_SESSION['cart'] = array();

// Add categories as keys, rather than values
$category = 'Tops';
$_SESSION['cart'][$category][] = $productA;

$category = 'Trousers';
$_SESSION['cart'][$category][] = $productB;

// Loop through your cart
foreach($cart as $category => $products): ?>
    <h2><?php echo $category; ?></h2>

    <?php foreach($products as $product): ?>
        <div class="product">
            <?php echo $product->name; ?>
        </div>
    <?php endforeach; ?>
<?php endforeach; ?>

R.

Thanks for your reply.

The category's are not predefined or fixed, they come through the array via session based on the selection the user makes. What I need to do is find a way to organise the output by the value of the category and only display the category once so I'm not outputting duplicates.

$_SESSION['cart'] = array("category" => $_SESSION['category'], "product" => $_SESSION['product']);

Cheers

The point stands, and if you need to keep your current session structure, you could build up an array at show time (with category as key and products array as value).

Still not getting this to work.

With the above code, I replaced the strings with the Session variable for each category.

$category = $_SESSION['category'];
$_SESSION['cart'][$category][] = $productA;

The product variable I'm not sure how to use. Should I put an array in there to get the product values?

I'm doing my best to learn this stuff, it's not my strong point and I'd relly hate to piss people off because of my lack in understanding.

foreach($_SESSION['cart'] as $v) $products[$v['category']][] = $v['product'];

Then, loop through $products as explained above. Or var_dump it and take a look at what's in it.

I worked on your suggestion using var_dump and I managed to rework my array

and it looks like this

$category = $_SESSION['category'];
$_SESSION['cart'][$increment] = array($category => array(
                                        "catno" => $_SESSION['catno'],
                                        "quantity" => $_SESSION['qty'],
                                        "cost" => $cost));

array 'Tops' => 
        array 'catno' => string 'CWIBLCOL60-60' (length=13)
              'quantity' => string '20' (length=2)
              'cost' => int 33

is the key correct and how would I output this?

Better way to view your array is following, after setting your array, write following 3 lines at the end of your code.

echo "<pre>";
print_r($_SESSION['cart']);
echo "</pre>";

Why is print_r better than var_dump? Just asking. Also, pre is nice but it's easier to view the source imho.

Actually there is no difference, Its my own feeling, I prefer print_r. Otherwise most important part is using pre for displaying values in proper format.

@besherek, change increment to category, add 2 brackets, and remove the outer array.

You can put a pre around var_dump, too, but if you look at the source, it's readable, too.

There is a difference. var_dump shows the variable type, including empty strings, false booleans, null values, etc, whereas print_r would just show an empty array index given the current example.

Thanks for your help twiss. Still displaying as per usual though.

I managed to get the key to work, but it's still outputting duplicate categories.

CategoryA
Product1
CategoryA
Product2
CategoryB
Product3

When I need

CategoryA
Product1
Product2
CategoryB
Product3

If there is a demo out there or tutorial, I'll check those out.

@Besherek - try modifying the code you posted to look something like the following:

$category = $_SESSION['category'];

$_SESSION['cart'][$category][] = array(
    'catno' => $_SESSION['catno'],
    'quantity' => $_SESSION['qty'],
    'cost' => $cost
);

When adding elements to an array, it isn't necessary to manually specify a numeric index, as this is done automatically.

Also, with the above, if the category index already exists, the product will simply be added to the existing array. Otherwise a new index will be created.

R.

Could you post your new code?

Member Avatar for diafol

Only print the title when it changes

Example:

$cat = "";

//$arraydata contains data

foreach($arraydata as $key => $val){
  if($key != $cat){
    echo "<h2>$key</h2>";
    $cat = $key;
  }
  echo "<p>$val</p>";
}

That's a possibility too, but the point of rewriting the array was eliminating the need of doing that. I.e., you can just first echo the key, and then loop to the value array.

Member Avatar for diafol
foreach($arraydata as $key => $val){
  if($key != $cat){
    echo "<h2>$key</h2>";
    $cat = $key;
  }
  echo "<p>Product: {$val[0]} Qty: {$val[1]} Cost: {$val[2]}</p>";
}

would be my method if using a 'flat' product,qty,cost under the catalog

$arraydata[CATALOG_NO][][0] // productname
$arraydata[CATALOG_NO][][1] // quantity
$arraydata[CATALOG_NO][][2] // cost

Yes, but what if you sort the products not on category but on price, for example?

Member Avatar for diafol

Fair one, but I don't think he asked for that. Did he? I ain't gonna read it all again, My head's all funny from trying to decipher how many dimensions of array are being discussed. :(
I just went for the simplest method (IMO) for the brief.

Yes, that's true. Well, both are possible I guess.

Okay guys, thanks heaps, I got it to work. It's displaying just like I want it. Just need to hook up the pricing/totals and all set.

I used a combination of everyone's suggestions and got it to work.

Appreciate everyone's help/patience and for me was a great laerning curve.

$_SESSION['cart'] = array();

$category = $_SESSION['defstoreName'];
     
$_SESSION['cart'][$category][] = array(
'catno' => $newtemplate,
'quantity' => $quantity,
'cost' => $cost
);

$cat = "";

foreach($_SESSION['cart'] as $key => $value)
{
  if($key != $cat)
  {
    echo $key; // OUTPUT CATEGORY TITLE
    $cat = $key;

    foreach ($value as $product)
    {
      // OUTPUT PRODUCT INFO
      echo $product['catno'] . ' ' . $product['qty'] . ' ' . $product['cost']; 
    }
  }
}

Okay, great that it works.

One thing you could try (as using both methods at the same time seems pointless to me in this case) to comment out line 12, 16, 17, 19 and 26, and see if it keeps working. If not, uncomment them again of course.

@twiss, still works after commenting out those lines, good call.

$_SESSION['cart'] = array();
 
$category = $_SESSION['defstoreName'];
 
$_SESSION['cart'][$category][] = array(
'catno' => $newtemplate,
'quantity' => $quantity,
'cost' => $cost
);
 
foreach($_SESSION['cart'] as $key => $value)
{
  echo $key; // OUTPUT CATEGORY TITLE
 
  foreach ($value as $product)
  {
    // OUTPUT PRODUCT INFO
    echo $product['catno'] . ' ' . $product['qty'] . ' ' . $product['cost'];
  }
}

Okay, nice. Have fun selling products :)

Cheers,

Work is for a label/sticker ordering site with png/pdf artwork proofing on the fly. Setting up the proofing was by far much easier than these arrays.

Back again, I was looking at removing items, I've managed to remove products, but unable to remove a category when it is empty. Any ideas?

Using the previous solved code

cart.php

<a href="remove.php?item=<?php echo $subkey; ?>">remove</a>

remove.php

$remove = '';
  if(isset($_GET['item']))
  {
    $remove = $_GET['item'];
  }

  if ($remove != "")
  {
    unset($_SESSION['cart'][$_SESSION['defstoreName']][$remove]);
  }

  Header ("Location: cart.php");

I've managed to get the remove empty category (which is named defstoreName) to work, however, it will only remove the category I am in session with.

if(empty($_SESSION['cart'][$_SESSION['defstoreName']]))
{
  unset($_SESSION['cart'][$_SESSION['defstoreName']]);
}

Worked it out. From what I can tell it all works as intended. If anyone has a cleaner method, let me know. This is the best I can do for the moment.

I thought I should post it incase someone else in a similar situation needs a reference.

cart.php

$_SESSION['cart'] = array();
 
$category = $_SESSION['defstoreName'];
 
$_SESSION['cart'][$category][] = array(
'catno' => $newtemplate,
'quantity' => $quantity,
'cost' => $cost
);
 
foreach($_SESSION['cart'] as $key => $value)
{
  if(empty($value))
  {
    unset($key);
  }
  else
  {
    echo $key; // OUTPUT CATEGORY TITLE
  }
 
  foreach ($value as $product)
  {
    // OUTPUT PRODUCT INFO
    echo $product['catno'] . ' ' . $product['qty'] . ' ' . $product['cost'];
  }
}

<a href="remove.php?cat=<?php echo $key; ?>&item=<?php echo $subkey; ?>">remove</a>

remove.php

$remove = '';
if(isset($_GET['item']))
{
  $remove = $_GET['item'];
}
$catremove = '';
if(isset($_GET['cat']))
{
  $catremove = $_GET['cat'];
}
	  
$_SESSION['defstoreName'] = $catremove;

if ($remove != "")
{
  unset($_SESSION['cart'][$_SESSION['defstoreName']][$remove]);
}

Header ("Location: cart.php");
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.