Jump to content

Looping through session variable array


GD

Recommended Posts

Hi everyone,

 

I am very new to PHP and trying to learn so please bear with me.  I have a simple form which passes fields to a PHP script:

 

<form method="post" action="cartaction.php">

<p>

<input type="submit" name="submit" value="Buy" />

<input type="hidden" name="cartaction" value="add" />

<input type="hidden" name="item" value="steelcasserole" />

</p>

</form>

 

 

I am trying to produce a shopping cart type page which will display the item(s) purchased.  The problem is I have more than one submit button on the page for different products but with the same fields.

 

I have tried to create the cartaction.php script to save the information from the form in a session variable which will allow me to output the item(s) purchased into this page prior to sending everything to a checkout page.  I can get the information to appear for a single item but the problem is I want to output the details for each product added to the cart.  At the moment, when I go back to the products page and try to add a new item to the shopping cart it just replaces the previous item that was there rather than retaining it and adding a new item underneath.

 

I realise its probably really obvious but I am really new to this and getting myself confused!  Any help on how to add an item then be able to go back to the products page (with the submit buttons for each product) and add a new item underneath the existing item in the shopping cart would be much appreciated!  The code I have so far is:

 

$submit = $_POST["submit"];

 

//If form is submitted, call the function and save all data into the array $_SESSION['form']

if($submit = "Buy"){setSessionVars();}

 

function setSessionVars() {

 

    foreach($_POST as $fieldname => $fieldvalue) {

        $_SESSION['form'][$fieldname] = $fieldvalue;

 

        } 

 

echo "<table> <tr> <td>" .'<img src="images/'.$_SESSION['form']['item'].'.jpg"' . "<td/> <td>"

. $_SESSION['form']['item'] . "</td> <td>" . '<input type="text(30)" name="value" value="1" />

<input type="submit" name="puchasednum" value="Update This One Item" />' . "</td> </tr> </table>";

 

};

?>

 

 

I have the session_start() function at the very top of every page.  I have also attached the entire files for the two pages I talk about above.  Thanks

 

Graham

17972_.php

17973_.php

Link to comment
Share on other sites

Your session should contain an array like

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

Then you can put each new item in that array.

$item = array();

foreach($_POST as $fieldname => $fieldvalue) {

        $item[$fieldname] = $fieldvalue;

     

        } 

$_SESSION['cart'][] = $item;

 

not tested.

 

You may want to use the item's ID number as the key for that array to make it easy to update/delete items. Your items should all have unique IDs then you could even just do

$_SESSION['cart'][$item_id'] = $quantity;

 

 

Link to comment
Share on other sites

Hi again,  I have modified the code as below but not sure if I have implemented properly as I am still having the same problem.  Probably looking at the problem too long has turned my brain to mush!

 

<?php

 

$submit = $_POST["submit"];

 

//If form is submitted, call the function and save all data into the array $_SESSION['form']

if($submit = "Buy"){setSessionVars();}

 

function setSessionVars() {

 

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

 

$item = array();

foreach($_POST as $fieldname => $fieldvalue) {

        $item[$fieldname] = $fieldvalue;

     

        } 

$_SESSION['cart'][] = $item;

 

echo "<table> <tr> <td>" .'<img src="images/'.$item['item'].'.jpg"' . "<td/> <td>"

. $item['item'] . "</td> <td>" . '<input type="text(30)" name="value" value="1" />

<input type="submit" name="puchasednum" value="Update This One Item" />' . "</td> </tr> </table>";

}

?>

 

Thank you for your help its much appreciated.

Link to comment
Share on other sites

Sorry, you can't do  $_SESSION['cart'] = array(); every time. Check first to see if $_SESSION['cart'] isset. If not, then make it an array - if it's already set and you do that line, you make it a new empty array.

Link to comment
Share on other sites

here try this

<?php
$submit = $_POST["submit"];

//If form is submitted, call the function and save all data into the array $_SESSION['form'] 
if($submit = "Buy"){setSessionVars();} 

function setSessionVars() {

$item = array();
foreach($_POST as $fieldname => $fieldvalue) {
	$item[$fieldname] = $fieldvalue;
}  
$_SESSION['cart'] = $item;
         
          echo "<table> <tr> <td> <img src=\"images/{$item['item']}.jpg\" /><td/> <td>
          {$item['item']}</td> <td> <input type=\"text(30)\" name=\"value\" value=\"1\" />
          <input type=\"submit\" name=\"puchasednum\" value=\"Update This One Item\" /> </td> </tr> </table>";
}
?>

Link to comment
Share on other sites

 

<?php
//If form is submitted, call the function and save all data into the array $_SESSION['form'] 
if($_POST['submit'] == "Buy"){ unset($_POST['submit']); setSessionVars(); } 

function setSessionVars() {
   if ( !isset($_SESSION['cart']) ) $_SESSION['cart'] = array();
   $_SESSION['cart'] = array_merge($_SESSION['cart'], $_POST);
   echo <<<HTML
   <table>
      <tr>
         <td><img src="images/{$item['item']}.jpg" /></td>
         <td>{$item['item']}</td>
         <td><input type="text" name="value" value="1" maxlength="30" /><input type="submit" name="puchasednum" value="Update This One Item" /></td>
      </tr>
   </table>
HTML;
}
?>

Link to comment
Share on other sites

Thanks everyone - your great help is very much appreciated! The table showing a single item purchased is showing up nicely but I still have the problem that I need to be able to go back and purchase further items and have them appear in the shopping cart underneath the item(s) already in there.  At the moment when I go back and try to add another item to the cart it just replaces the item that was in there rather than adding an additional table underneath.  Any ideas on how I can retain the original session variable on the shopping cart page and add another instance of them for a new product underneath?

 

Many thanks

Link to comment
Share on other sites

Your existing code can only add one item at a time to the cart (the form's 'Buy' submit button next to each displayed item), so there are no $_POST variables to be looping over. Ideally, you only need the submit button (so that you know you are adding to the cart) and the item id as $_POST data.

 

Your design needs to be data driven. That means that you write general purpose code and you let the data control what is displayed and operated on, even for category navigation menus. You should have one table that holds all your items (your table named 'pans' implies you are planning on making different tables for different types of things.)

 

You should not have separate pages like copperrange.php, steelrange.php. You should have one page where you pass the category id on the end of the url, something like shop.php?cat=123 You also query for the matching items and display them, rather than hard-coding each separate item you show on a page.

 

The following is some re-factored code for a shop.php and cataction.php page that will get you a lot closer to what you need -

 

shop.php -

<?php
// session_start(); // if there are no $_SESSION variables used on this page, no need for session_start()

$cat_list = array(1=>'Copper Range',2=>'Steel Range'); // your list of category id's/descriptions (in a real application this would be retrieved from a database table)

// get/condition the requested category
$category = isset($_GET['cat']) ? intval($_GET['cat']) : false;
if($category < 1 || !isset($cat_list[$category])){
// handle an invalid category here...

// either setup a default $category or produce a menu to select a category...

$category = 1; // for demo purposes, select the first available category

}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title><?php echo $cat_list[$category]; ?></title>
<link rel="stylesheet" href="styles/site.css" type="text/css" />
  <?php  
//we need to access the stock table in the database to get the pan prices on this page
// include the external script created to connect to database so it can be called from this page
include ('databaseconnect.php');

// your database credentials should be inside of a file you include so that you don't need to repeat them in each file that needs them or accidentally post it in a forum

//define some constants that can be used as parameters for the database connection function
define ('HOST', 'localhost');	// database server address
define ('USER', 'xxxxxx');		// database user name
define ('PASS', 'xxxxxxxx');		// database password

// pass these constants to the connect_db function to connect to my database
$connection = connect_db(HOST, USER, PASS);

// unless your connect_db function selects a database, your existing code and this code will fail at the mysql_query statement
?>
</head>
<body>
<div id="header">
<h1><?php echo $cat_list[$category]; ?></h1>
</div>
<div id="mainblock">
<table>
<?php
// query for the items under the selected category and output them using a loop
$query = "SELECT * FROM items WHERE cat_id = $category ORDER BY name";
$result = mysql_query($query,$connection) or die("Query failed: $query<br />Error: " . mysql_error($connection));
if(mysql_num_rows($result) < 1){
	// no items for this category, handle that here...
	echo "No items found under category: $cat_list[$category].";
} else {
	// one or more items found
	while($row = mysql_fetch_assoc($result)){
		echo "<tr><td><img src='images/{$row['image']}' alt='{$row['name']}' /></td>";
		echo "<td><p>{$row['name']}<br />{$row['description']}<br />";
		printf("£%.2f", $row['price']/100);
		echo "</p></td>";
		echo "
		<td>
			<form method='post' action='cartaction.php'>
				<p>
					<input type='submit' name='submit' value='Buy' />
					<input type='hidden' name='item' value='{$row['id']}' />
				</p>
			</form>
		</td>";
		echo "</tr>";
	}
}
?>
</table>
</div>
<div id="footer">
<form method="post" action="cartaction.php">
	<p>
		<input type="submit" name="submit" value="Show Cart or Checkout" />
		<input type="hidden" name="cartaction" value="display" />
	</p>
</form>
<ul class="navlist">
	<li><a href="index.php">Go Back Home</a></li>
</ul>
</div>
</body>
</html>

 

cartaction.php -

<?php
session_start();
$cat_list = array(1=>'Copper Range',2=>'Steel Range'); // your list of category id's/descriptions (in a real application this would be retrieved from a database table)
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Pans for Your Kitchen</title>
<link rel="stylesheet" href="styles/site.css" type="text/css" />
</head>
<body>
<div id="header">
<h1>Your Shopping Cart</h1>
</div>
<div id="mainblock">
<?php
// get/condition input
$submit = isset($_POST["submit"]) ? trim($_POST['submit']) : false;

//If form is submitted, call the function and add the item to the cart
if($submit == "Buy"){addToCart();}

// your functions should be named to indicate what specific operation they perform
function addToCart() {
// if cart does not exist, create an empty cart
if(!isset($_SESSION['cart'])){
	$_SESSION['cart'] = array();
}
// get/condition the requested item
$item = isset($_POST['item']) ? intval($_POST['item']) : false;
if($item < 1){
	// handle an invalid item number here...

	die('Invalid Item'); // for demo purposes, just die

}
// $item is an integer > 0, add to cart/increase quantity in cart
if(!isset($_SESSION['cart'][$item])){
	// doesn't exist in cart, create it
	$_SESSION['cart'][$item] = 0;
}
// increment quantity in cart
$_SESSION['cart'][$item]++;

// display any information that you see fit here...
}

// generate category navigation menu
$nav_menu = '';
foreach($cat_list as $key=>$value){
$nav_menu .= "<li><a href='shop.php?cat=$key'>$value</a></li>\n";
}
?>
</div>
<div id="footer">
<form method="post" action="checkout.php">
	<p><input type="submit" name="submit" value="Goto Checkout" /></p>
</form>
<ul class="navlist">
	<?php echo $nav_menu; ?>
</ul>
</div>
</body>
</html>

Link to comment
Share on other sites

Here is some re-re-factored logic for the cartaction.php file that moves the php logic to the start of the file (gets it out of your HTML document), shows a method of preventing duplicate data submission in the form processing code, and adds a showCart() function -

<?php
// moved function definitions to start of file. Typically you would have these in a separate file and include that file.
function addToCart() {
// if cart does not exist, create an empty cart
if(!isset($_SESSION['cart'])){
	$_SESSION['cart'] = array();
}
// get/condtion the requested item
$item = isset($_POST['item']) ? intval($_POST['item']) : false;
if($item < 1){
	// handle an invalid item number here...

	die('Invalid Item'); // for demo purposes, just die

}
// $item is an integer > 0, add to cart/increase quantity in cart
if(!isset($_SESSION['cart'][$item])){
	// doesn't exist in cart, create it
	$_SESSION['cart'][$item] = 0;
}
// increment quantity in cart
$_SESSION['cart'][$item]++;

header("Location: {$_SERVER['SCRIPT_NAME']}"); // redirect to (GET) the current page to clear $_POST data
exit;
}

function displayCart($connection,$cat_list){
if(!isset($_SESSION['cart']) || empty($_SESSION['cart'])){
	echo "Your cart is empty!";
} else {
	$items = implode(',',array_keys($_SESSION['cart']));
	$query = "SELECT * FROM items WHERE id IN($items) ORDER BY name";
	$result = mysql_query($query) or die("Query failed: $query<br />Error: " . mysql_error($connection));
	echo "<table><tr><th>Category</th><th>Item Name</th><th>Description</th><th>Qty</th><th>Price</th><th>Total</th></tr>";
	while($row = mysql_fetch_assoc($result)){
		echo "<tr><td>{$cat_list[$row['cat_id']]}</td>";
		echo "<td>{$row['name']}</td><td>{$row['description']}</td>";
		echo "<td>{$_SESSION['cart'][$row['id']]}</td><td>".sprintf("£%.2f", $row['price']/100)."</td><td>".sprintf("£%.2f", $_SESSION['cart'][$row['id']] * $row['price']/100)."</td></tr>";
	}
	echo "</table>";
}
}

session_start();

include ('databaseconnect.php');
$connection = connect_db(HOST, USER, PASS); // NOTE: This code assumes that you have defined these constants in the databaseconnect.php file and that you are selecting a database somewhere in your code

$cat_list = array(1=>'Copper Range',2=>'Steel Range'); // your list of category id's/descriptions (in a real application this would be retrieved from a database table)

// generate navigation menu
$nav_menu = '';
foreach($cat_list as $key=>$value){
$nav_menu .= "<li><a href='shop.php?cat=$key'>$value</a></li>\n";
}

// get/condition input
$submit = isset($_POST["submit"]) ? trim($_POST['submit']) : false;

//If form is submitted from a 'Buy' button, add the item to the cart
if($submit == "Buy"){addToCart();}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Your Shopping Cart</title>
<link rel="stylesheet" href="styles/site.css" type="text/css" />
</head>
<body>
<div id="header">
<h1>Your Shopping Cart</h1>
</div>
<div id="mainblock">
<?php

displayCart($connection,$cat_list);

?>
</div>
<div id="footer">
<form method="post" action="checkout.php">
	<p><input type="submit" name="submit" value="Goto Checkout" /></p>
</form>
<ul class="navlist">
	<?php echo $nav_menu; ?>
</ul>
</div>
</body>
</html>

Link to comment
Share on other sites

Thank's very much - that's a massive help.  The application I'm building specifies that there has to be a copper range page and a steel range page but there will only be one table for all items for all items as they will  only be pans on sale.

 

Your expertise has been a great help and I will work through your suggestions.  Thanks again

 

Graham

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.