I'm building a simple PHP 'shopping cart' (which is actually just a "My Favourites list" kind of function - no payments etc.) and it's been going pretty well so far. I've been modifying code that I found on a tutorial about creating a simple shopping cart, and it's serving its purpose very well at this stage.

However, I've hit a brick wall when it comes to retrieving an array and printing/echo'ing the contents of the array (within an existing foreach loop). Here is what the code would look like if I wasn't to have the array being echo'd, so you can see what I'm after (note the red text 'finishes' - it's Product Finishes that I'm wanting to output [Stainless Steel, Black Anodised Steel etc.]).

function showCart() {
	global $db;
	$cart = $_SESSION['cart'];
	if ($cart) {
		$items = explode(',',$cart);
		$contents = array();
		foreach ($items as $item) {
			$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
		}
		$output[] = '<form action="/xx/xx/cart.php?action=update" method="post" id="cart">';
		foreach ($contents as $id=>$qty) {
			$sql = "SELECT * FROM products WHERE id = '$id'";
			$result = $db->query($sql);
			$row = $result->fetch();
						
			$product_name = $row['name'];
			$related_product_image_1 = $row['image_filename_1'];
			
			$find ="/ /"; 
			$replace ="-"; 
			
			$space_remover = preg_replace($find, $replace, $product_name);
			$new_product_name = strtolower($space_remover);
			
			if ($related_product_image_1 != 'nothing') { 
				$product_image = $related_product_image_1;
			} else {
				$product_image = 'No_image.gif';
			}
			
			extract($row);
			
			$output[] = '<div class="shortlist_spacer"></div>';			
			$output[] = '<div class="shortlist_item">';
			$output[] = '<div class="shortlist_item_image"><a href="/xx/xx/products/'.$id.'/'.$new_product_name.'/"><img src="/xx/xx/imgsize.php?w=115&amp;img=http://www.xx.com/xx/xx/images/products/'.$product_image.'" width="115" border="0" alt="'.$name.'" /></a><p><a href="/xx/xx/cart_delete.php?action=delete&id='.$id.'">Remove from Shortlist</a></p></div>';
			$output[] = '<div class="shortlist_item_info"><table width="450" style="width:450px;" cellpadding="0" cellspacing="0" border="0">';
			$output[] = '<tr><td colspan="2"><span class="shortlist_item_title"><a href="/xx/xx/products/'.$id.'/'.$new_product_name.'/">'.$name.'</a></span></td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Product Code</td>';
			$output[] = '<td width="335">'.$sku.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Brand/Designer</td>';
			$output[] = '<td width="335">'.$brand.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Finishes</td>';
			$output[] = '<td width="335">'.$finishes.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Price ea.</td>';
			$output[] = '<td width="335">$'.$price.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Quantity</td>';
			$output[] = '<td width="335"><input type="text" name="qty'.$id.'" value="'.$qty.'" size="2" maxlength="2" /></td></tr>';
			$output[] = '</table></div>';
						
			$total += $price * $qty;
			$output[] = '</div>';
			$output[] = '<div class="clear"></div>';
		}
		$output[] = '<p>Grand total: <strong>&pound;'.$total.'</strong></p>';
		$output[] = '<div><button type="submit">Update cart</button></div>';
		$output[] = '</form>';
	} else {
		$output[] = '<p>Your Shortlist is empty.</p>';
	}
	return join('',$output);
}

So the above code is fine for displaying everything other than the Finishes. I then took the following code which I use on the 'View Product' page (to output the values from the $finishes array), and tried inserting it, but I'm getting all sorts of strange results. Sometimes (depending on where I place the following code) I get a list of every value x 10, it seems to add to itself in a random order etc..

Is it a simple case of finding the right place to slot in the below code? I tried placing this where the red '$finishes' is above.

// inspect the product_finishes_lookup table to find out which finishes are available for this product
				
$finishes_lookup_result = @mysql_query('SELECT finishes_id FROM product_finishes_lookup WHERE product_id="'.$id.'"');
				
// turn each of the results from the lookup table into an array so we can use each array to output the details of each finish
				
while ($array = mysql_fetch_array($finishes_lookup_result))
				{
				$finish_data[] = $array[0];
				}
				
// turn each array into a variable called 'value' which we can then use to query the finishes database for
// the finishes associated with this product
				
foreach ($finish_data as $value) {
				
$finishes_grabber = @mysql_query("SELECT * FROM finishes WHERE id = '$value' ORDER BY name ASC");
				
while ( $row = mysql_fetch_array($finishes_grabber) ) {
				$finishes_name = $row['name'];
				
echo('' . $finishes_name . '<br />');
}
}

Any advice would be hugely appreciated, even just a slight push in the right direction and I should be able to figure it out.

Just in case I haven't made this post clear, ideally I should be able to echo something that will look like this:

'Stainless steel <br />
Aluminium <br />
Black anodised steel <br />'

Hey.

I just have a couple of suggestions.

#1
Your $_SESSION['cart'] element. You can use session elements as arrays. There is no need to serialize all the items into a single element.
Meaning, rather than do:

<?php
function addToCart($id) {
    $_SESSION['cart'] .= "$id,";
}
function printCart() {
    $itemList = explode(",", $_SESSION['cart']);
    array_pop($itemList);
    $items = array();
    foreach($itemList as $_item) {
        $items[$_item] = isset($_items[$_item]) ? $_items[$_item] + 1 : 1;
    }
    foreach($items as $_id => $_qantity) {
        echo "{$_id} = {$_quanity}";
    }
}
?>

You could do:

<?php
function addToCart($id) {
    $_SESSION['cart'][$id] = isset($_SESSION['cart'][$id]) ? $_SESSION['cart'][$id] + 1 : 1;
}
function printCart() {
    foreach($_SESSION['cart'] as $_id => $_qantity) {
        echo "{$_id} = {$_quanity}";
    }
}
?>

It's just a lot cleaner this way.

#2
For your second code example, you could use a JOIN, so you don't have to execute multiple queries. It also simplifies the PHP somewhat.

<?php
$sql = "SELECT 
            f.name
        FROM product_finishes_lookup AS l
        INNER JOIN finishes AS f
            ON f.id = l.finishes_id
        WHERE l.product_id = {$id}";
$result = mysql_query($sql) or die(mysql_error());

while($row = mysql_fetch_row($result))
{
    echo $row['name'], "<br />";
}
?>

That should work.

Thank you very much Atli - your code (the 2nd part, regarding Product Finishes) looked great and it gave me hope, however it's not returning a result. I tried a few different places to insert the code, but to no avail. I also tried editing the code to "where l.product_id = '94'" just to see if there was an issue getting the '$id' variable, but this didn't do anything different.

I don't think it's an actual error with the code, because when I swapped around the 'product_finishes_lookup' and 'finishes' tables in the SELECT statement, I got an error about the field not existing. It's just a case of no result being returned.

I'm thinking it has something to do with the way the data is coming from the database - I've never seen an "output[]" method of printing/echo'ing the results of a query, and this is preventing me from putting further PHP code into each "output[]" line.

Or was I meant to use both the code snippets you provided? I wasn't sure where to place that code from your first new snippet.

This is how I placed in the 2nd snippet you gave me:

function showCart() {
	global $db;
	$cart = $_SESSION['cart'];
	if ($cart) {
		$items = explode(',',$cart);
		$contents = array();
		foreach ($items as $item) {
			$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
		}
		$output[] = '<form action="/clients/xx/cart.php?action=update" method="post" id="cart">';
		foreach ($contents as $id=>$qty) {
			$sql = "SELECT * FROM products WHERE id = '$id'";
			$result = $db->query($sql);
			$row = $result->fetch();
						
			$product_name = $row['name'];
			$related_product_image_1 = $row['image_filename_1'];
			
			$find ="/ /"; 
			$replace ="-"; 
			
			$space_remover = preg_replace($find, $replace, $product_name);
			$new_product_name = strtolower($space_remover);
			
			if ($related_product_image_1 != 'nothing') { 
				$product_image = $related_product_image_1;
			} else {
				$product_image = 'No_image.gif';
			}
			
			extract($row);

$sql = "SELECT 
            f.name
        FROM product_finishes_lookup AS l
        INNER JOIN finishes AS f
            ON f.id = l.finishes_id
        WHERE l.product_id = {$id}";
$result = mysql_query($sql) or die(mysql_error());

while($row = mysql_fetch_row($result))
{
    echo $row['name'], "<br />";
}

			$output[] = '<div class="shortlist_spacer"></div>';			
			$output[] = '<div class="shortlist_item">';
			$output[] = '<div class="shortlist_item_image"><a href="/clients/xx/products/'.$id.'/'.$new_product_name.'/"><img src="/clients/xx/imgsize.php?w=115&amp;img=http://www.xx.com/clients/xx/images/products/'.$product_image.'" width="115" border="0" alt="'.$name.'" /></a><p><a href="/clients/xx/cart_delete.php?action=delete&id='.$id.'">Remove from Shortlist</a></p></div>';
			$output[] = '<div class="shortlist_item_info"><table width="450" style="width:450px;" cellpadding="0" cellspacing="0" border="0">';
			$output[] = '<tr><td colspan="2"><span class="shortlist_item_title"><a href="/clients/xx/products/'.$id.'/'.$new_product_name.'/">'.$name.'</a></span></td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Product Code</td>';
			$output[] = '<td width="335">'.$sku.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Brand/Designer</td>';
			$output[] = '<td width="335">'.$brander.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Colour/Finish</td>';
			$output[] = '<td width="335">'.$finishes.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Price ea.</td>';
			$output[] = '<td width="335">$'.$price.'</td></tr>';
			$output[] = '<tr><td width="115" class="blue_text">Quantity</td>';
			$output[] = '<td width="335"><input type="text" name="qty'.$id.'" value="'.$qty.'" size="2" maxlength="2" /></td></tr>';
			$output[] = '</table></div>';
						
			$total += $price * $qty;
			$output[] = '</div>';
			$output[] = '<div class="clear"></div>';
		}
		$output[] = '<p>Grand total: <strong>&pound;'.$total.'</strong></p>';
		$output[] = '<div><button type="submit">Update cart</button></div>';
		$output[] = '</form>';
	} else {
		$output[] = '<p>Your Shortlist is empty.</p>';
	}
	return join('',$output);
}

So I'm not sure if it's an error in where I'm placing it, or if it's just the strange output[] thing and 'extract($row)' thing that's preventing your code from working.

Also, the green part of text above ('$finishes') – this is just coming straight from the 'products' database, I'm not sure how to override this and have it refer to the red code snippet (so it'd output the results of your code snippet, rather than just outputting the value of 'finishes' in the products database).

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.