...

View Full Version : Session array for pseduo cart



loomer
05-29-2007, 05:06 AM
Hi,

I'm working on a website where I would like to use sessions to store a handful of values. I have browsed through various code examples and I believe a session array is the way to go but I'm still a little unsure how to get started.

I have a product catalog page populated from a mySQL database listing many products. Each product has a product code and description that need to be stored if the user clicks on it. When the user is finished with the catalog the values are then listed in a form and the user fills out the other info and an email is generated to send to the company. The basic product info is used for a price quote.

I believe a session array would work best here because I only need to store multiple values of the same thing (product code, description). I know how to store the first session value but I am unsure how to store each successive value. This will depend on how many products the user has added. So I need to know how to store the new product to the next unset array index. Also, I'm not sure how to list all the products in the session array on the form page.

I think I need to use isset and foreach but I just need a little guidance and how to get started. I would appreciate any help you can provide.

Fumigator
05-29-2007, 06:35 AM
You would assign values to the $_SESSION variable just like you assign values to any other variable. Examples:



$_SESSION['memberID'] = 10001;
$_SESSION[] = 'This will add a numeric array element to the $_SESSION array.';
$_SESSION['userInfo'] = mysql_fetch_assoc($result);


Read up on arrays (http://us2.php.net/manual/en/language.types.array.php) in the PHP manual.

firepages
05-29-2007, 03:09 PM
Each product has a product code and description that need to be stored if the user clicks on it.
not really ... you really only need to store the database id of the item and other info like number of items , page specific discounts etc/whatever.

Ideally you will fetch the descriptions and other meta data and display only when required (at checkout/cart contents etc)

I like to go one further with shopping carts, I store the shopping cart contents in a class and the save the class as a session variable..


<?php
/*create the cart if ! exists, else bring it back to life*/
include_once '/path/to/shopping_cart.class.php';
if(empty($_SESSION['scart'])){
$scart = new scart();
}else{
$scart = unserialize($_SESSION['scart']);
}

$scart->add('item_id', 'num', 'etc');
$_SESSION['scart']=serialize($scart);
?>

loomer
05-29-2007, 08:26 PM
Thanks for your help. I understand your methodology. I just need to store the product IDs and I can query the database for the rest of the info upon the checkout type of page. I'm not quite sure how to store a new item in the next successive session variable. For example, I have no problems storing the first item in the session. But each additional product I'm not sure how to store the value in the next empty slot in the array. On the flip side there is reading all the values of the array too.

Sorry, I grasp the concept but I'm just a little slow for the code. I'll give it another shot when I get home from work tonight.



not really ... you really only need to store the database id of the item and other info like number of items , page specific discounts etc/whatever.

Ideally you will fetch the descriptions and other meta data and display only when required (at checkout/cart contents etc)

I like to go one further with shopping carts, I store the shopping cart contents in a class and the save the class as a session variable..


<?php
/*create the cart if ! exists, else bring it back to life*/
include_once '/path/to/shopping_cart.class.php';
if(empty($_SESSION['scart'])){
$scart = new scart();
}else{
$scart = unserialize($_SESSION['scart']);
}

$scart->add('item_id', 'num', 'etc');
$_SESSION['scart']=serialize($scart);
?>

whizard
05-29-2007, 08:33 PM
//for each item
$_SESSION[] = 'ITEM ID';
//to get the info from the DB
for($i=0,$i++)
{
if(isset($_SESSION[$i]))
{
//Query Database here
}
else
{
break;
}
}

This code will allow you to store other (non item ID) SESSION variables, as long as you give them a name for their key. It will loop through all the numbered $_SESSION vars (all the Item IDs) and retrieve each items info from the DB

HTH
Dan

aedrin
05-29-2007, 09:01 PM
That's a bad script. Do not store your values directly in $_SESSION. You did not put a proper condition in your for. Getting inventive does not make it better. Also, never run a single query like that for each product -unless- you have to (such as your query cannot work with IN).

Use something like: $_SESSION['cart']



// setup cart near the top of the page
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}




// add $amount of $productId to cart
if (!isset($_SESSION['cart'][$productId])) {
// ensure we have something in the array here
$_SESSION['cart'][$productId] = 0;
}
$_SESSION['cart'][$productId] += $amount;




// query database for all descriptions
$productIds = array_keys($_SESSION['cart']);

$query = "SELECT * FROM products WHERE id IN (" . implode(",", $productIds) . ")";

// then loop through the query results to display the products. you can use the $productIds array to keep them in the same order as the cart if you need to.


Use these snippets to understand how it will work. You will need more code to get it to work.

whizard
05-29-2007, 09:14 PM
Thanks for the critique, lol

"You did not put a proper condition in your for."

Sorry, I meant to add $i = $i;

Can you elaborate on some of your other comments (strictly for my education, I'm sure you're right)?

For instance, why is it bad to store stuff directly in $_SESSION?
What do you mean by, "Getting inventive does not make it better."?
"Also, never run a single query like that for each product -unless- you have to (such as your query cannot work with IN)." - Makes sense.

Dan

aedrin
05-29-2007, 09:21 PM
You were being inventive/creative when not needed when you put in that break condition.

Adding $i = $i; is also not the right way. To loop through an array just do one of these:



$total = sizeof($array);
for ($i = 0; $i < $total;$i++) {
// do stuff
}




foreach ($array as $key => $value) {
// do stuff
}




$i = sizeof($array);
while (i--) {
// do stuff
}



For instance, why is it bad to store stuff directly in $_SESSION?

$_SESSION is the only thing you have to store session information.

If you store it directly into session like this:



$_SESSION[$productId] = $amount;


What happens when you always want to store who is logged in? You can't use $_SESSION anymore, it is already being used as the cart. Now you'll have to update all of your code to store it like this:



$_SESSION['cart'][$productId] = $amount;


Always think ahead. If within a short time you can think of a situation where you'd need to be able to extend something, you probably will need to. And you should program accordingly to support it.

loomer
05-29-2007, 09:37 PM
Thanks very much for your suggested code. That definitely gives me a big push in the right direction. I'll give it a try tonight.

I appreciate your help.


That's a bad script. Do not store your values directly in $_SESSION. You did not put a proper condition in your for. Getting inventive does not make it better. Also, never run a single query like that for each product -unless- you have to (such as your query cannot work with IN).

Use something like: $_SESSION['cart']



// setup cart near the top of the page
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}




// add $amount of $productId to cart
if (!isset($_SESSION['cart'][$productId])) {
// ensure we have something in the array here
$_SESSION['cart'][$productId] = 0;
}
$_SESSION['cart'][$productId] += $amount;




// query database for all descriptions
$productIds = array_keys($_SESSION['cart']);

$query = "SELECT * FROM products WHERE id IN (" . implode(",", $productIds) . ")";

// then loop through the query results to display the products. you can use the $productIds array to keep them in the same order as the cart if you need to.


Use these snippets to understand how it will work. You will need more code to get it to work.

loomer
05-30-2007, 05:35 AM
Update: I have successfully implemented your code suggestions but I occasionally come across this error on the checkout page:


You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '00000039,00000009,00000011) ORDER BY dynamicCatalog.dcatalog_prolinecode, dynami' at line 3

Below is the code the error is referring to. I believe the problem is when the checkout page is called without passing along a product value in the address. I think it's trying to do a query but is missing a value.



session_start();

// setup cart near the top of the page
if (!isset($_SESSION['quotecart'])) {
$_SESSION['quotecart'] = array();
}


// Name of mySQL database
$database="national_products";
include("Includes/connect.php");

if ($_GET[productcode]) {
$inq_productcode = $_GET[productcode];
$inq_productdesc = $_GET[productdesc];
}


// add $amount of $productId to cart
if (!isset($_SESSION['quotecart'][$productcode])) {
// ensure we have something in the array here
$_SESSION['quotecart'][$productcode] = 0;
}
$_SESSION['quotecart'][$productcode] = $inq_productdesc;


// query database for all descriptions
$productIds = array_keys($_SESSION['quotecart']);


// then loop through the query results to display the products. you can use the $productIds array to keep them in the same order as the cart if you need to.

if ($_GET[productcode]) {
$query_rs0 = "SELECT dcatalog_productcode, dcatalog_prolinecode, dcatalog_productdesc FROM dynamicCatalog
INNER JOIN dynamicCatalog_masterxref ON dynamicCatalog.dcatalog_productcode=dynamicCatalog_masterxref.dproductxref_productcode
WHERE dcatalog_productcode IN (" . implode(",", $productIds) . ")
ORDER BY dynamicCatalog.dcatalog_prolinecode, dynamicCatalog_masterxref.dproductxref_sortkey";

$rs0 = mysql_query($query_rs0) or die(mysql_error());
$count=mysql_numrows($rs0);
$i=0;
}
?>


The error seems to occur when I browse through the site on webpages other than the product catalog and menu.

Any ideas?

Thank you.

meth
05-30-2007, 08:17 AM
Validate values before using in query?

Try:



// query database for all descriptions
$arr_ids = array_keys($_SESSION['quotecart']);

//validate values
foreach($arr_ids as $k => $v) {
if( empty($v) || !is_numeric($v) ) unset($arr_ids[$k]);
}

$str_ids = implode( ',' , $arr_ids );



if ($_GET[productcode]) {
$query_rs0 = "SELECT dcatalog_productcode, dcatalog_prolinecode, dcatalog_productdesc FROM dynamicCatalog
INNER JOIN dynamicCatalog_masterxref ON dynamicCatalog.dcatalog_productcode=dynamicCatalog_masterxref.dproductxref_productcode
WHERE dcatalog_productcode IN (" . $str_ids . ")
ORDER BY dynamicCatalog.dcatalog_prolinecode, dynamicCatalog_masterxref.dproductxref_sortkey";

aedrin
05-30-2007, 03:25 PM
'00000039,00000009,00000011)

If those are your 'product ID's then you need to do it a little different.

Use something like this instead:


$query = "SELECT * FROM products WHERE id IN ('" . implode("','", $productIds) . "')";

Notice the added single quotes. Don't run this query with an empty cart as it would generate an error.


I believe the problem is when the checkout page is called without passing along a product value in the address. I think it's trying to do a query but is missing a value.

Never assume what the problem is. Always find the actual problem first before doing any attempted fixes.

You can use print_r() on $_SESSION['cart'] to see what the values are it's trying to get. If that looks alright (no empty array keys), you could echo out the $query variable. Just write it to a log file, then when you come across the error, immediately go back to the log file.

Or even better, write yourself a decent query function such as this and use it in all your code.



function query($sql) {
$result = mysql_query($sql);
if (!$result) {
echo '<p>Query='.$sql.'</p>';
die("Query failed: " . mysql_error());
return null;
}
return $result;
}


That way you can see both the error, and what the actual query was. And while you're debugging you could put the logging in this function and only have to manage one point of debugging when you're done.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum