The shopcart.php page provides customer access to their shopping cart items. It summarizes their purchases, permits them to change their order quantities, and is the gateway for finalizing their order. There are some intricacies in coding this page, so pay attention.

Displaying the Shopping Cart
The following code creates the shopping cart display. This code appears within the main division of the page to produce the output illustrated above. Note that the entire division encompasses a form that is submitted back to this page to change the item quantities.
<tr>
Warning: odbc_connect() [function.odbc-connect]: SQL error: [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key 'Temporary (volatile) Jet DSN for process 0x17ec Thread 0xb70 DBC 0xd95344c Jet'., SQL state S1000 in SQLConnect in E:\WebSite\Tutorials\PHP\ECommerce\php00-11.php on line 50
Warning: odbc_exec(): supplied argument is not a valid ODBC-Link resource in E:\WebSite\Tutorials\PHP\ECommerce\php00-11.php on line 56
Warning: odbc_fetch_array(): supplied argument is not a valid ODBC result resource in E:\WebSite\Tutorials\PHP\ECommerce\php00-11.php on line 58
Warning: odbc_close(): supplied argument is not a valid ODBC-Link resource in E:\WebSite\Tutorials\PHP\ECommerce\php00-11.php on line 82
The first portion of the code produces the headings for the page and creates the table headers for the shopping cart listing. The current system date is displayed along with the customer's order number, which is being maintained in the $_SESSION[OrderNo] variable.
Retrieving Shopping Cart Items
Items in the shopping cart for this customer are keyed to the order number and are retrieved by issuing the SQL command,
$sql="SELECT OrderItem,OrderQuantity FROM ShopCart WHERE OrderNo = '$_SESSION[OrderNo]'";The resulting $rsCart recordset contains the two selected fields OrderItem and OrderQuantity for each record. These fields are assigned to variables. The other two fields in the records (OrderNo and OrderDate) are not needed for this purpose. Now, it is a matter of iterating through the records and producing the table rows showing the selected items.
We don't yet, though, have available all of the information to be displayed across the rows. In addition to the OrderItem and OrderQuantity contained in the shopping cart, the table shows the title of the item and its price. These values are in the Products table. So, these fields are retrieved for the associated product by creating the $rsProd recordset and issuing the SQL statement,
$sqlProd = "SELECT ItemTitle, ItemPrice FROM Products WHERE ItemNumber = '$OrderItem'";to retrieve the ItemTitle and ItemPrice for the product. These values are also assigned to variables.
For each line-item displayed, we also show the purchase amount. This $OrderAmount variable is calculated by multiplying the quantity ordered ($OrderQuantity) times the price of the product ($OrderPrice). Also, as the script iterates through the shopping cart records, the $OrderTotal is accumulated by adding to it each $ItemAmount. Note that the OrderTotal variable is initialized to 0 prior to beginning the display loop.
We've now gathered the information necessary to display a line of the table:
echo "<tr>
<td>$OrderItem </td>
<td>$OrderTitle</td>
<td><input type=\"text\" name=\"Q$OrderItem\" size=\"2\" class=\"qtybox\"
value=\"$OrderQuantity\"></td>
<td style=\"text-align:right\">$$OrderPrice</td>
<td style=\"text-align:right\">$$OrderAmount</td>
</tr>";
We're displaying the variables holding the data extracted from the ShopCart and Products tables and the calculated amount. In the case of the $OrderPrice and $OrderAmount items, the PHP number_format() function is used to format the values to two decimal positions. Now we need to explain what's going on with the OrderQuantity field.
Naming Quantity Fields
The page division is enclosed with in a <FORM> tag since the customer is given an opportunity to change the amounts ordered and to resubmit the form to update these quantities. For this purpose, then, the $OrderQuantity for each item purchased needs to be placed into a form field, as is done with the code,
<input type="text" name="Q<?php echo $OrderItem ?>" size="2" class="qtybox"The key to getting the form to work properly is in the naming convention used for this field. Note that the name assigned to this text field is "Q<?php echo $OrderItem ?>"; that is, the letter "Q" (which arbitrarily stands for "quantity") is followed by the item number ($OrderItem) for the product whose $OrderQuantity appears in this field. Taking as example the shopping cart illustrated at the top of this page, the name of the quantity field for the first item in the list would be "QBU1111" and the name of the field for the second item would be "QOS1111".
The reason for using this naming technique is two-fold. In the first place, we don't know how many different quantity fields will appear on the form. There will be as many fields as there are products purchased. So, unlike our previous experience with forms, we cannot define and name these fields in advance. In the second place, we cannot use the same name for all the fields. If, for example, we were to simply name the field "Quantity", then there would be as many Quantity fields as there were products purchased. This would cause real, impossible, problems in trying to determine which quantity was associated with which product.
So, we need a naming convention that, first, permits an unknown number of quantity fields to be defined and named on-the-fly and, second, uniquely identifies the product associated with the quantity appearing in that field. The current naming convention handles both issues rather well. The "Q" is used to identify this as a quantity field (an important identifier that we'll use below) and the appended OrderItem provides a unique name that also identifies the product associated with the quantity in the field. We will discuss below how a script sorts out this information to update the quantity fields with changed values.
Order Summary Lines and Buttons
After the script is finished iterating through the shopping cart items and listing all of the purchases, the shipping cost ($OrderShipping) is calculated as 2% of the OrderTotal and a couple of summary lines are displayed.
<tr>
<td colspan="4" style="text-align:right">Shipping </td>
<td style="text-align:right"><?php echo $OrderShipping ?></td>
</tr>
<tr>
<th colspan="4" style="text-align:right">Order Total </th>
<td style="border-style:solid"><b><?php echo $OrderTotal ?></b></td>
</tr>
Finally, two buttons are displayed: the "Update" button to submit any changes made in the product quantities and a "Checkout" button to finalize the order. This latter button is discussed on the following page dealing with submission of the order for credit card purchase.
Customers can visit the shopcart.php page at any time, even before any purchases are made. When this happens, though, there is no reason for the person to see or to have access to these two buttons. They are only pertinent to customers who have selected products for purchase. Therefore, their display is contingent upon customers having items in their shopping carts, namely, when their OrderTotal amounts are not $0.00. This condition is used to determine whether or not to display the buttons.
<?php if($OrderTotal != 0) {?>
<div style="width:375px; line-height:8pt">
<input type="submit" name="UpdateButton" class="buttonM"
style="float:left; margin-right:5px" value="Update"
onMouseOver="OverMouse(this)"; onMouseOut="OutMouse(this)">
<span class="small">Click to update changed quantities. Enter new quantity
or enter 0 to cancel purchase of item.</span>
</div>
<?php } ?>
</form>
<?php if ($OrderTotal != 0) {?>
<div style="width:375px; line-height:8pt">
<form action="http://.../creditcheck.php" method="post">
<input type="hidden" name="ReturnURL" value="http://.../ordercapture.php">
<input type="hidden" name="CompanyID" value="WebWarehouse.com">
<input type="hidden" name="CustomerID" value="<?php echo $_SESSION[OrderNo]?>">
<input type="hidden" name="Amount" value="<?php echo $OrderTotal ?>">
<input type="submit" name="CheckoutButton" class="buttonM"
style="float:left;margin-right:5px" value="Checkout"
onMouseOver="OverMouse(this)"; onMouseOut="OutMouse(this)">
<span class="small">Click to finalize on-line purchase through secure connection
to Credit Payment Systems.</span>
</form>
</div>
<?php } ?>
Iterating through a Submitted Form
When the user changes one or more product quantities and clicks the "Update" button to submit the form, the information is passed back to this shopcart.asp page. The shopcart.asp page, then, contains a script to update these changes to the ShopCart table. This script appears at the top of the page to intercept the changes when the form is submitted.
The purpose of this script is to update the ShopCart table with the product quantities transmitted from the form. What we know about this situation is that there are an unknown number of quantity fields, each with the letter "Q" prefixing their names; and we know that the form values arriving at this page can be in any order.
Up until now we have always known the names and number of fields on our forms. That's because we have designed the forms, named the fields, and have determined how many fields there were. But that's not the case here. We don't know how many fields there are (it depends on how many items are in the shopping cart); and we don't know their names (except that they begin with the letter "Q"). So we can't handle forms processing as we have previously.
PHP scripting, however, has a method for solving these problems. It permits us to iterate through any and all $_REQUEST items and to be able to determine the submitted field names and associated values, even if we don't know what they are. This method is encompassed within the special For Each...Next loop. Its general structure when applied to forms is
|
foreach($_REQUEST as $key => $value) |
where $_REQUEST is an associative array containing all of the name/value pairs for the form controls on a page. This loop iterates through each of the name/value pairs submitted from a form. On each iteration, the $key variable contains the name portion of the name/value pair, and the $value references the value associated with that name. The array takes on the form $_REQUEST[$key] = $value for each name/value pair associated with the form.
We can use this iteration structure, then, to look through the items submitted to update the shopping cart and determine their field names and values. When we encounter a field name that begins with the letter "Q", then we'll know that this is a quantity field containing a value for updating the ShopCart table. We'll also be able to figure out from the name the product to which the quantity applies.
Updating the Shopping Cart
Below is shown the entire script for updating the shopping cart when the customer clicks the "Update" button on the form.
if ($_POST[UpdateButton] == "Update")
{
$conn2 = odbc_connect('Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\inetpub\wwwroot\PHPTutorial\Ecommerce\databases\ecommerce.mdb','','');
foreach($_REQUEST as $key => $value)
{
if (strpos($key,"Q") === 0 )
{
$OrderItem = substr($key,1);
$OrderQuantity = $value;
if (is_numeric($OrderQuantity))
{
if ($OrderQuantity == 0)
{
$sqlCartUpdate = "DELETE FROM ShopCart WHERE OrderNo='$_SESSION[OrderNo]' AND OrderItem='$OrderItem'";
}
else
{
$sqlCartUpdate = "UPDATE ShopCart SET OrderQuantity='$OrderQuantity' WHERE OrderNo='$_SESSION[OrderNo]'
AND OrderItem='$OrderItem'";
}
$rsCartUpdate = odbc_exec($conn2,$sqlCartUpdate);
}
}
}
odbc_close($conn2);
}
The first order of business is linking to the eCommerce.mdb database. A Recordset Object is not needed here since updates are made directly through SQL commands executed through the Connection Object.
Now, a foreach loop is established to iterate through the names and values collected in the $_REQUEST[] array when the form was submitted to the server. The variable named $key is used to reference the field names appearing in the Collection.
As the script looks at each item, it checks to see if the name of the field begins with the letter "Q":
if (strpos($key,"Q") === 0 ) {The PHPstrpos() function is used to test if the first character (or the character at position 0) of the form control name is equal to "Q." If so, then this is a quantity field containing a value for updating the shopping cart. Here it is important to note that the PHP "=== indentical to" comparison operator is used instead of the "== equal to" comparison operator. This is necessary because the strpos() function requires the "===" for testing its returned values.
Next, the script determines which product record to update and what the value of the quantity actually is:
$OrderItem = substr($key,1);We know that the product item number associated with this quantity field is contained in the $key variable. It is, in fact, the right-most six characters of the field name. So, these six characters are extracted from the variable by using the PHP substr() function and are placed into variable $OrderItem. Then, the $value associated with this field is assigned to variable $OrderQuantity. Now we have the two pieces of information needed to update the $ItemQuantity field for this product in the ShopCart table.
Before updating the product quantity, we should check to make sure that the customer entered a number. Through mistyping an invalid character could be entered into the field. So, a numeric check is applied to the $OrderQuantity.
if (is_numeric($OrderQuantity))If something other than a number is in the field, the quantity updating for this item is skipped and the next form field is accessed.
The quantities submitted with the form can represent additional quantities purchased, or they can have a 0 value to indicate that the item is to be removed from the shopping cart. This value is tested and one of two SQL statements is formatted and executed.
In the case of a deletion or an update, the action is applied to the ShopCart record with an OrderNo field matching the current $_SESSION[OrderNo], and with an $OrderItem field matching the $OrderItem from the submitted form. A DELETE statement removes the entire record from the table; an UPDATE statement changes the $OrderQuantity field in the table to the $OrderQuantity value from the submitted form.
The script iterates through all of the items submitted with the form, checking the name of the field for a "Q." If it finds this, then it extracts the product number from the name and assigns it and the quantity value to variables that are used in updating the ShopCart table. At the end of the $_REQUEST[] Collection, the connection to the database is closed and the script ends.
Iterating through the $_REQUEST[] Collection
It might be worthwhile using an example of submitted values to visualize the Request.Form Collection. It we assume the shopping cart items illustrated at the top of this page, then, when the "Update" button is clicked, the following Request.Form Collection is created:
$_REQUEST[] Collection| Name | Value |
|---|---|
| QOS1111 | 2 |
| UpdateButton | Update |
| QBU1111 | 1 |
One principal thing to notice is that the items in the collection are not necessarily in the order in which they appear on the form; plus, the button that was clicked is also part of the Collection. Consider, now, iterating through these items with a foreachloop in which variable $key references the names and $value references the values:
foreach($_REQUEST as $key => $value) {You can see here the data items that the script has to deal with and perhaps better understand the machinations of the script to extract product numbers and process product quantities.