Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Session Arrays 1

Status
Not open for further replies.

sipps

Technical User
Feb 9, 2003
133
GB
Hi all,

I am well out of my depth here, but I need to get this done, I have been trying for ages!

It is basically a shopping cart, but I want to be able to do it myself, silly I know!!

The user clicks on a link next to a desired item, this sends them to the cart.php page with that Item_ID in the URL (GET).

I have set up a session in both pages.
In the cart.php page, I have set up a session array, and I want to populate this array with what ever the customer has clicked on, sending the Item_ID into the cart.
Basically, I wrote this, as I am still learning!:

(cart.php)

session_start();
$newitem = $HTTP_GET_VARS['Item_ID'];
if (empty($item)) {$k = 0; $item = $newitem;} else {$k++; $item = $newitem;}

$HTTP_SESSION_VARS['Products']['Item_ID'] = array();
$HTTP_SESSION_VARS['Products']['Item_ID'][$k] = "$item";

Now, I was hoping that everytime the user clicked the "add to basket" link, it would bring a new Item_ID and populate it in the session array, but no, this is not working.

That was the first problem, the second problem is that I want to loop through this array lower down in the page and print out the items relating to each Item_ID stored in the session array.

This means that I need to get a recordset, to retreive the items, and loop through the recordset to get each item where that Item_ID is in the session array.
What SELECT statement do I write to get the records;

SELECT *
FROM item
WHERE Item_ID = '$HTTP_SESSION_VARS[Products][Item_ID][$k]'

doesn't bring back anything at all, so I don't know what to write. Also, I need to loop through this recordset bringing back all the items that are in the basket.

I am sorry that this is quite a heavy problem, I have been reading through my books but I cannot seem to even get the simple stuff working!
I can get one Item_ID into the session array, but when I leave the cart and click another item, it writes over the Item_ID that was previously there.

Thank you for any help!!!

sipps
 
The problem may be in this line:

$HTTP_SESSION_VARS['Products']['Item_ID'] = array();

If you are running that line every time the script runs (that is, you don't have logic around it to make it run only when necessary), then that line is setting the session variable $_SESSION['Products']['Item_ID'] to be an empty array.

Also, you are using $k as an array index. Do you have $k as a session variable, too? Otherwise, you're always going to be writing to $_SESSION['Products']['Item_ID'][0].


What I see, from this and other questions you have asked in this forum, is that you have some experience doing continuous programming. That is, you have written application programs that run on a computer console. The thing is that web programming is discontinuous -- each script invokation is a single, stand-alone program. You seem to be having to get into the frame of mind that every script you run must be a complete program in and of itself.

Think of Want the best answers? Ask the best questions: TANSTAAFL!
 
And as far as your SQL query construction problem goes, what do your error-handling script lines report?

What does your SQL query look like, once the concatenation takes place? I can't judge what you might be doing wrong, as you have stripped down your script pieces too far. Want the best answers? Ask the best questions: TANSTAAFL!
 
Thank you sleipnir214,

I am no programmer as you can tell!! But I do try, and I am learning so much. I understand that I have to get into the mindset of web programming, and it is hard, it is not like being back in collage where you could just ask someone to take you through something!

I know what I want to do, but it is the process of putting it in to code that I find difficult!

I have re-written the page as per your advice, I needed to set the array once if the user had never been to that page before, else I needed to increment k so it would put the new Item_ID into the next array slot.

$newitem = $HTTP_GET_VARS['Item_ID'];
if (empty($item)) {$k = 0; $item = $newitem; $HTTP_SESSION_VARS['Products']['Item_ID'] = array(); session_register($k);} else {++$k; $item = $newitem;}

$HTTP_SESSION_VARS['Products']['Item_ID']['$k'] = "$item";

Again, this is not inserting the new Item_ID into the next available slot in the array. It is just overwriting what was already in there. By a bit of testing, I don't think that it is looking at the else part of the statement at all.

Again, I cannot seem to be able to loop through the array as well, it is not like the other do - while loops that I have used to loop through a recordset. I may be able to carry on working on this though, I would just like to be able to populate the array!

Thanks for your help and advice, it really is very much appreciated by a frustrated learner!!!

sipps
 
What I would do for testing purposes: At the beginning of the script, immediately following session_start(), perform a print_r on $_SESSION. Then immediately after the code which attempts to append the new product id, issue print_r against $_SESSION again.

I would also footprint my code to better follow the flow of your code -- put print statements in places so you can see what statements are being run.

I would explicitly test whether $_SESSION['Products']['Item_ID'] is itself an array (use the is_array() function), rather than testing $item for existence. The way your code is written, if the script is run at an inappropriate time, the session will be wiped out.

BTW, You don't really need $k. If $foo is an array, then the statement "$foo[] = 'some value';" will append the value to a new element at the end of the array.

In any regard, you are using session_register() incorrectly. If you want to register $k as a session variable, you issue "session_register('k');" not "session_register($k);". The latter will register as a session varible a variable whose name is the same as the value of $k.

I notice that in one place you are using session_register(), but in another you are manipulating $_SESSION directly. I recommend that you pick one method and use it all the time. I recommend that you manipulate $_SESSION directly. I also recommend that if your PHP version is newer than 4.1.0 that you use $_SESSION rather than $HTTP_SESSION VARS, $_POST rather than $HTTP_POST_VARS, $_GET rather than $HTTP_GET_VARS, etc. See the online manual here: for more information, particularly the explanation of "superglobal".

The PHP online manual also states that if you are going to be manipulating $_SESSION directly, not to use session_register() at all. If you need another session variable, "$_SESSION['foo'] = 3;" is equivalent to "$foo = 3; session_register('foo');" Want the best answers? Ask the best questions: TANSTAAFL!
 
In any regard, this small two pieces of code works for me. You can use your browser's "Back" button to go back to the html page in order to submit more products.

test_products.html:
Code:
<html><body><form method=&quot;post&quot; action=&quot;test_cart.php&quot;>
<select name=&quot;item_id&quot;>
	<option value=&quot;1a&quot;>Apple</option>
	<option value=&quot;2b&quot;>Butter</option>
	<option value=&quot;3c&quot;>Candy</option>
	<option value=&quot;4d&quot;>Dog Food</option>
</select>
<input type=&quot;submit&quot;>
</form></body></html>

test_cart.php:
Code:
<?php
session_start();

print &quot;<pre>Before:\n&quot;;
print_r ($_SESSION);

if (!array_key_exists('Products', $_SESSION) || !is_array ($_SESSION['Products']['Items']))
{
	$_SESSION['Products']['Items'] = array();
}

$_SESSION['Products']['Items'][] = $_POST['item_id'];

print &quot;After:\n&quot;;
print_r ($_SESSION);
?>

Want the best answers? Ask the best questions: TANSTAAFL!
 
sleipnir214,

Thank you again so much. I am really getting there now, I have sorted out my session stuff, and have made much better progress, and I'm less frustrated!

Basically, I used you example code to list all my Item_IDs that were getting input into the array when using the &quot;add to basket&quot; link. This works great, and I can loop through the array and print them out.
I am still having trouble looping through the array and putting the Item_ID into a SELECT query to get that items details.

This is what I have so far:

session_start();

print &quot;<pre>Before:\n&quot;;
print_r ($_SESSION);

if (!array_key_exists('Products', $_SESSION) || !is_array ($_SESSION['Products']['Items']))
{
$_SESSION['Products']['Items'] = array();
}
$productresult = count ($_SESSION['Products']);
$itemresult = count ($_SESSION['Products']['Items']);


$_SESSION['Products']['Items'][] = $_GET['Item_ID'];


print &quot;After:\n&quot;;
print_r ($_SESSION);

Now I have used the count() function because I thought I should use this to loop through the array a certain number of times to run the select query, is this correct?

When I run the query, it always brings back the last Item_ID from the array:

foreach ($_SESSION['Products']['Items'] as $prod)

mysql_select_db($database_digitalhome, $digitalhome);
$query_getitemsforcart = &quot;SELECT * FROM item WHERE Item_ID = '$prod'&quot;;
$getitemsforcart = mysql_query($query_getitemsforcart, $digitalhome) or die(mysql_error());
$row_getitemsforcart = mysql_fetch_assoc($getitemsforcart);
$totalRows_getitemsforcart = mysql_num_rows($getitemsforcart);

I know I need some sort of loop here, but I am not sure how to write it, do I need a do - while loop or a for loop?
I took the foreach from further down the page where I print all the Item_ID's to the screen:

<?php
foreach ($_SESSION['Products']['Items'] as $prod) {
echo(&quot;<tr><td>$prod</td></tr>&quot;);
}
?>

I have been reading through my MySQL and PHP4 book, but neither seem to have any hint of how to loop through arrays and put the value into an SQL statement.

Again, thank you for taking the time to give me a massive learning curve today, I feel much better now I can see some results!!!

sipps
 
There is no canonical way to traverse an array. You can use any of foreach, for, or while. Generally speaking, a for-loop is easiest for traversing a numerically-indexed array, and a foreach loop for an associative array.

I wouldn't look up every item in the cart every time I need to display it. I would look up each item's information as its added to the cart and store the information in the session array.

Create a query like:

$query_getitemsforcart = &quot;SELECT * FROM item WHERE Item_ID = '&quot; . $_GET['Item_ID'] . &quot;'&quot;;

Take a look at this modification of the script test_cart.php that I posted earlier. It shows adding the description and price and adds the feature of only incrementing a count if the item is already in the cart. The structure of $_SESSION['Product'] changes slightly:

Code:
<?php
session_start();

//Here we would perform a MySQL database lookup of product description and price from item_id.  But for illustrative purposes:

$mysql_simulation_array = array
(
	'1a' => array ('desc' => 'Apple', 'price' => 0.11),
	'2b' => array ('desc' => 'Butter', 'price' => .99),
	'3c' => array ('desc' => 'Candy', 'price' => .49),
	'4d' => array ('desc' => 'Dog Food', 'price' => 1.25)
);

$desc = $mysql_simulation_array[$_POST['item_id']]['desc'];
$price = $mysql_simulation_array[$_POST['item_id']]['price'];


print &quot;<pre>Before:\n&quot;;
print_r ($_SESSION);

if (!array_key_exists('Products', $_SESSION) || !is_array ($_SESSION['Products']))
{
	$_SESSION['Products'] = array();
}

if (! array_key_exists($_POST['item_id'], $_SESSION['Products']))
{
	$_SESSION['Products'][$_POST['item_id']] = array ('Desc' => $desc, 'Price' => $price, 'Count' => 1);
}
else
{
	$_SESSION['Products'][$_POST['item_id']]['Count']++;
}


print &quot;After:\n&quot;;
print_r ($_SESSION);
?>
Want the best answers? Ask the best questions: TANSTAAFL!
 
Thank you again sleipnir214,

I will put that into my query, and try and populate the session with the output from MySQL.

One thing with you script is that I can add a first item, and then go back to add a second item, once I submit it, php.exe encounters an error and shuts it down, do you think it will do this for when I have created my script?

The error message I received was:

Server error!
Error message:
Premature end of script headers: php.exe
If you think this is a server error, please contact the webmaster
Error 500
localhost
03/28/03 10:32:24

Anyway, I will get on to this right away, thank you!

sipps
 
I'm sorry, I still have problems populating the session array! Thank you for your patience with me, I can say you're teaching me a lot though if that's any consellation!

I am using mysql to get the information on the Item_ID passed in the URL to populate the array.

The query I am using:

mysql_select_db($database_digitalhome, $digitalhome);
$query_getitemsforcart = &quot;SELECT * FROM item WHERE Item_ID = '$_GET[Item_ID]'&quot;;
$getitemsforcart = mysql_query($query_getitemsforcart, $digitalhome) or die(mysql_error());
$row_getitemsforcart = mysql_fetch_assoc($getitemsforcart);
$totalRows_getitemsforcart = mysql_num_rows($getitemsforcart);

This block is right at the top of the page, not sure how much difference that makes?!

I then set up some variables with the information I need from the query:

$itemid = $row_getitemsforcart['Item_ID'];
$itemname = $row_getitemsforcart['Item_Name'];
$itemprice = $row_getitemsforcart['Sell_Price'];

And these go in to populate the array construct you wrote:

session_start();
print_r ($_SESSION);
$mysql_items = array
(
'$itemid' => array ('Item_Name' => '$itemname', 'Sell_Price' => '$itemprice')
);

$name = $mysql_items[$row_getitemsforcart['Item_ID']]['Item_Name'];
$price = $mysql_items[$row_getitemsforcart['Item_ID']]['Sell_Price'];

And this is where I don't think it's populating the array. I have the rest of the code as you wrote it:

print &quot;<pre>Before:\n&quot;;
print_r ($_SESSION);

if (!array_key_exists('Products', $_SESSION) || !is_array ($_SESSION['Products']))
{
$_SESSION['Products'] = array();
}

if (! array_key_exists($_GET['Item_ID'], $_SESSION['Products']))
{
$_SESSION['Products'][$_GET['Item_ID']] = array ('Item_Name' => $name, 'Sell_Price' => $price, 'Count' => 1);
}
else
{
$_SESSION['Products'][$_GET['Item_ID']]['Count']++;
}


print &quot;After:\n&quot;;
print_r ($_SESSION);

?>

The print out of the array shows that the Item_ID is being used, but nothing else (This is the 12 and the 17):

Array
(
[Products] => Array
(
[12] => Array
(
[Item_Name] =>
[Sell_Price] =>
[Count] => 1
)

[Item_ID] =>
)

)
After:
Array
(
[Products] => Array
(
[12] => Array
(
[Item_Name] =>
[Sell_Price] =>
[Count] => 1
)

[Item_ID] =>
[17] => Array
(
[Item_Name] =>
[Sell_Price] =>
[Count] => 1
)

)

)

I am not sure why it is not populating the array, or how I can get it to populate it. Also, I have been trying to do a foreach loop to printout the values in the array lower down on the page, but I get nothing back from this:

<?php
foreach ($_SESSION['Products']['Item_ID'] as $prod) {
echo(&quot;<tr><td>$itemid</td><td>$name</td><td>$price</td></tr>&quot;);
}
?>

I feel like I'm taking up a lot of your time, and I don't mean to! I am really grateful for your help, I hope you don't mind all my questions!

Thanks again,

sipps
 
I have apparently managed to confuse you. You are doing stuff in your code you do not need to do.

I have created a table on my database server called &quot;item&quot;, which has the following data in it:

[table &quot;item&quot;]
Code:
+---------+------------+-----------+
| Item_ID | Item_Price | Item_Name |
+---------+------------+-----------+
| APL     |       0.11 | Apple     |
| BUT     |       0.99 | Butter    |
| CND     |       0.50 | Candy     |
| DOG     |       1.25 | Dog Food  |
+---------+------------+-----------+

I have now modified the file that produces the form from which you can select an item. Whereas before the page was static HTML, it is now a PHP script which pulls its data to display from the table above:

[test_products.php]
Code:
<?php
print '
<html><body><form method=&quot;POST&quot; action=&quot;test_cart.php&quot;>
<select name=&quot;Item_ID&quot;>';

$dbh = mysql_connect ('localhost', 'test', 'test');
mysql_select_db ('test');
$query = &quot;SELECT * from item&quot;;
$rh = mysql_query ($query, $dbh) or die(mysql_error());

while ($item = mysql_fetch_assoc($rh))
{
	print '
	<option value=&quot;' . $item['Item_ID'] . '&quot;>' . $item['Item_Name'] . '</option>';
}

print '
</select>
<input type=&quot;submit&quot;>
</form></body></html>';
?>

The form produced submits to test_cart.php, which I have modified as follows:

[test_cart.php]
Code:
<?php
/*	if you are using GET-method instead of POST-method,
	all references to $_POST will have to be replace
	with references to $_GET
*/

print '
<html><body><form method=&quot;POST&quot; action=&quot;test_cart.php&quot;>
<select name=&quot;Item_ID&quot;>';

$dbh = mysql_connect ('localhost', 'test', 'test');
mysql_select_db ('test');
$query = &quot;SELECT * from item&quot;;
$rh = mysql_query ($query, $dbh) or die(mysql_error());

while ($item = mysql_fetch_assoc($rh))
{
	print '
	<option value=&quot;' . $item['Item_ID'] . '&quot;>' . $item['Item_Name'] . '</option>';
}

print '
</select>
<input type=&quot;submit&quot;>
</form></body></html>';
?>
Want the best answers? Ask the best questions: TANSTAAFL!
 
CORRECTION:

Sorry about that, I submitted when I meant to preview. Here is the actual code of test_cart.php:

[test_cart.php]
Code:
<?php
function update_session ()
{
//the following line needs to be changed
	$dbh = mysql_connect ('localhost', 'test', 'test');
	mysql_select_db('test', $dbh);
//the following line needs to be changed
	$query = &quot;SELECT Item_Name, Item_Price FROM item WHERE Item_ID = '$_POST[Item_ID]'&quot;;
	$drh = mysql_query($query, $dbh) or die(mysql_error());
	list ($itemname, $itemprice) = mysql_fetch_row($drh);
		
	$_SESSION['Products'][$_POST['Item_ID']] = array ('Desc' => $itemname, 'Price' => $itemprice, 'Count' => 1);
}


session_start();

print &quot;<pre>Before:\n&quot;;
print_r ($_SESSION);


if (array_key_exists ('Item_ID', $_POST))
{
	if (!array_key_exists('Products', $_SESSION) || !is_array ($_SESSION['Products']))
	{
		print 'make new';
		$_SESSION['Products'] = array();
		update_session();
	}
	else
	{
		if (! array_key_exists($_POST['Item_ID'], $_SESSION['Products']))
		{
			update_session();
		}
		else
		{
			$_SESSION['Products'][$_POST['Item_ID']]['Count']++;
		}
	
	}
}

print &quot;After:\n&quot;;
print_r ($_SESSION);
?>

The logic of the script has changed. Please not that it won't do anything unless data has been submitted to it. The code to actually change the session variable has been moved to a function -- I needed to be able to perform that code in two different places in my overall logic.

Some changes will need to be made if you want to try to run it. Take a look a the comments. Want the best answers? Ask the best questions: TANSTAAFL!
 
sleipnir214,

Thank you again! That worked well, it took the item name and price and entered it into the array. Every time I add a new item it makes a new Item_ID in the array and inputs the Item_Name and Sell_Price into that array. Thank you so much for getting it to work so well!!

Just a couple of questions about it.
Firstly, the two variables that were set up in the function, $itemname and $itemprice, are these available outside of that function, because everytime I try and print these further down in the page I get an &quot;undefined variable notice&quot;.

Also, I tried to print out each item with it's corresponding Item_ID, Item_Name and Sell_Price.
Firstly I made a test to see if I could loop through the array, using:

<?php
foreach ($_SESSION['Products'][$_GET['Item_ID'] as $prod) {
echo(&quot;<tr><td>$prod</td></tr>&quot;);
}
?>

This actually prints the last item out like so:
&quot;Sony Surround Sound Amp
159.99
1&quot;
Where &quot;1&quot; is the count, sometimes this can go as high as 11 though for one item, is this just because I refresh the page? I would like to just assign the Item_ID in the array to $cartitemid, the name of the item to $cartitemname and the price to $cartitemprice, but I have tried to assign these variables higher up in the page, but this has no effect.

The array is working well and looks like this after I have added two items:

After:
Array
(
[Products] => Array
(
[27] => Array
(
[Desc] => Samsung Home Theatre System - Wooden
[Price] => 1109.99
[Count] => 1
)

[25] => Array
(
[Desc] => Samsung FlatTV 635i
[Price] => 2099.00
[Count] => 2
)

)

)
Is there a way to split the array into two sections of desc and price and assign these to variables to print out so I can get every item showing lower down in the page?

Thank you so much for all your help on this sleipnir214, you really have made an impact on what I am trying to acheive. I hope I manage to one day sort all this out by myself with the knowledge I have gained!

Thanks

sipps
 
No, those variables are not available outside the function. They can be made so, either by returning the two values in an array, by using $GLOBALS['itemprice'] instead of $itemprice (making a new element in the superglobal array $GLOBALS will make a variable available in the outermost scope), ro by passing two variables by reference to the function so that the function can set the values.

It is possible that your browser is resubmitting the data when you refresh.

print_r () is really useful for debugging and as a quick output from demonstration code. if you want to format the output more prettily, then use loops to traverse the array, outputting the values with whatever HTML tags your page layout requires.
Want the best answers? Ask the best questions: TANSTAAFL!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top