⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch23.htm

📁 CGI programming is the hottest stuff to look out for in this book
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<HTML>

<HEAD>
   <TITLE>Chapter 23 -- Shopping Carts</TITLE>
   <META>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 23</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Shopping Carts</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>


<UL>
<LI><A HREF="#WhatAreShoppingCartCGIs" >What Are Shopping Cart CGIs?</A>
<LI><A HREF="#WhatThisChapterCovers" >What This Chapter Covers</A>
<LI><A HREF="#TheBasicElementsofaShoppingCartCG" >The Basic Elements of a Shopping Cart CGI</A>
<UL>
<LI><A HREF="#TheProductCatalog" >The Product Catalog</A>
<LI><A HREF="#UsingHiddenInputFieldstoMaintainSt" >Using Hidden Input Fields to Maintain State</A>
</UL>
<LI><A HREF="#OtherWaysofKeepingTrackofState" >Other Ways of Keeping Track of State</A>
<UL>
<LI><A HREF="#htaccessandREMOTE_USER" >htaccess and REMOTE_USER</A>
<LI><A HREF="#SessionIDEmbedding" >Session ID Embedding</A>
<LI><A HREF="#HTTpcookies" >HTTP Cookies</A>
<LI><A HREF="#CookieRecipes" >Cookie Recipes</A>
<LI><A HREF="#SettingCookieswithMETAHTTPequiv" >Setting Cookies with &lt;META HTTP-equiv&gt;</A>
<LI><A HREF="#BuildingCustomerProfiles" >Building Customer Profiles</A>
</UL>
<LI><A HREF="#DatabaseManagement" >Database Management</A>
<UL>
<LI><A HREF="#UsingDBMs" >Using DBMs</A>
</UL>
<LI><A HREF="#TheResultofYourLaborscartcgi" >The Result of Your Labors, cart.cgi</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<H2><A NAME="WhatAreShoppingCartCGIs"><FONT SIZE=5 COLOR=#FF0000>What
Are Shopping Cart CGIs?</FONT></A></H2>
<P>
The familiar shopping cart you push through the local supermarket
is an appropriate metaphor to chose for the type of convenience
and control people have come to expect from conducting transactions
in the everyday world. We push our shopping carts through the
aisles while we pick the items we want and ignore those that don't
interest us. We add and remove items from our carts almost without
thinking. The shopping cart CGI is an attempt to translate that
convenience and control to the purchases we can make on the World
Wide Web.
<P>
Shopping cart CGIs are essentially complex and feature-laden order
forms. The purpose of a shopping cart CGI is to make online purchases
as easy as possible for the potential consumer and to give them
the control over purchases to which they are so accustomed. In
one form or another, shopping carts are the direction that commerce
on the Internet is taking-they are the successor to the simple
order form.
<P>
Simple order forms<B> </B>are generally limited in the amount
of interactivity they give the customer. Generally, they allow
only a limited number of products and choices. With a shopping
cart CGI, you can browse through hundreds or thousands of different
items; choose the quantity, size, color of the items you want;
change your order; find out how much the order is going to cost;
leave the order process and come back to it later; make sure that
the items you want are currently in stock; and so on.
<H2><A NAME="WhatThisChapterCovers"><FONT SIZE=5 COLOR=#FF0000>What
This Chapter Covers</FONT></A></H2>
<P>
My goal in this chapter is not to develop for you the world's
most sophisticated, full-featured shopping cart CGI. After all,
there are enough possible features and shopping cart mechanisms
to fill an entire bookshelf. Each company's point-of-sale issues
are unique, and to make a program that could easily handle all
companies' needs is beyond the scope of this book (and in all
likelihood, beyond the scope of even the most sophisticated artificial
intelligence). Instead, the goal of this chapter is to produce
a reasonably simple shopping cart mechanism that the reader can
expand and customize according to his needs and to explore the
tools needed for more complex shopping programs.
<P>
In this chapter, you will learn:
<UL>
<LI><FONT COLOR=#000000>The basic elements of a shopping cart
CGI</FONT>
<LI><FONT COLOR=#000000>The core shopping cart features (add,
delete, view, and order)</FONT>
<LI><FONT COLOR=#000000>Sophisticated methods of keeping track
of shoppers</FONT>
<LI><FONT COLOR=#000000>The basics of product database management</FONT>
</UL>
<P>
Equipped with the tools and techniques learned in this chapter,
you should be able to build a shopping cart CGI of your own, one
full-featured enough for any application.
<P>
All the code in this chapter could have been written in any language,
but it is written in Perl. Among most CGI developers, Perl is
the language of choice because of the flexibility and efficiency
it affords. There is a whole class of features in Perl that the
author of the language, Larry Wall, refers to as &quot;metamagical.&quot;
These metamagical features such as dynamic array allocation and
interpolated variable names make life a lot easier for programmers.
<P>
There are those who claim that Perl sacrifices elegance and style
in favor of quick and dirty programming. This is probably a fair
assessment. Style and elegance are fine in a computer science
class room but generally mean very little to clients and superiors
who need working code and have deadlines to meet. If you write
code for a living in a high-pressure environment, Perl is a language
you will appreciate.
<H2><A NAME="TheBasicElementsofaShoppingCartCG"><FONT SIZE=5 COLOR=#FF0000>The
Basic Elements of a Shopping Cart CGI</FONT></A></H2>
<P>
This is probably a good time to clarify exactly what I am talking
about when I use the term &quot;cart.&quot; In the context in
which I use this term, a &quot;cart&quot; is really no more than
a list of products a visitor to your Web site wants to buy. The
&quot;cart&quot; starts out empty and as the customer browses
through your catalog, he adds or removes items from this list.
Keeping track of the current cart contents throughout the shopper's
visit to your site is the primary problem to be solved when designing
this sort of program.
<P>
By their very nature, shopping cart type programs make life difficult
for the programmer. This is often the trade-off when trying to
make things as simple and natural for the user as possible. With
simple order forms, the customer simply fills in or checks off
what she wants to order. In regular practice, that becomes quite
difficult. The first problem is simply the size of a potential
product catalog. Next is the nature of consumerism. People change
their minds or look for things in different orders than what you
might potentially expect. Most of these problems can be categorized
into the following areas:
<UL>
<LI><FONT COLOR=#000000>Organizing information in a catalog in
manageable sections</FONT>
<LI><FONT COLOR=#000000>Maintaining state between sections</FONT>
<LI><FONT COLOR=#000000>Cart manipulation features (add, remove,
and so on)</FONT>
<LI><FONT COLOR=#000000>Order pricing</FONT>
<LI><FONT COLOR=#000000>Order placing</FONT>
</UL>
<H3><A NAME="TheProductCatalog">The Product Catalog</A></H3>
<P>
Listing 23.1 is the simple product catalog that will be read into
our program. This is a file that could easily be generated by
any spreadsheet or database program. The fields are separated
by tabs, and records are separated by newlines.
<P>
If you are dealing with more complex data structures or Database
Management (DBM) files, refer to the section &quot;Database Management,&quot;
later in this chapter.<P>
<HR>
<BLOCKQUOTE>
<B>Listing 23.1. A simple product catalog.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">T&nbsp;&nbsp;&nbsp;&nbsp;&quot;I Love
CGI Programming Unleashed&quot; T-Shirt&nbsp;&nbsp;&nbsp;&nbsp;19.95
<BR>
hat&nbsp;&nbsp;&nbsp;&nbsp;&quot;Cloth &amp; Suede &quot;Unleashed&quot;
Hat&nbsp;&nbsp;&nbsp;&nbsp;9.95<BR>
keychain&nbsp;&nbsp;&nbsp;&nbsp;&quot;Unleashed&quot; Keychain&nbsp;&nbsp;&nbsp;&nbsp;4.95
<BR>
mousepad&nbsp;&nbsp;&nbsp;&nbsp;&quot;Unleashed&quot; Mouse Pad&nbsp;&nbsp;&nbsp;&nbsp;4.95
<BR>
bball&nbsp;&nbsp;&nbsp;&nbsp;&quot;Team CGI&quot; Baseball Jersy&nbsp;&nbsp;&nbsp;&nbsp;39.95
<BR>
plate&nbsp;&nbsp;&nbsp;&nbsp;&quot;Unleashed&quot; Commemorative
Plate&nbsp;&nbsp;&nbsp;&nbsp;29.95<BR>
coaster&nbsp;&nbsp;&nbsp;&nbsp;&quot;Unleashed&quot; Coasters,
set of 6&nbsp;&nbsp;&nbsp;&nbsp;4.95<BR>
nitelite&nbsp;&nbsp;&nbsp;&nbsp;&quot;Unleashed&quot; Glow-in-the-Dark
Nite-Lite&nbsp;&nbsp;&nbsp;&nbsp;2.95</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The three fields per item in this catalog are product code, product
description, and price. In this example, the product type simply
indicates the page on which the product appears. I have chosen
product codes that are very readable, but be aware that in most
cases, product codes are likely to be much more cryptic, along
the lines of pcX231 or GST352. In all likelihood, there will be
a system linking the product code to information about the product
itself (size, product type, expiration date, and so on). Finding
out about this system can give you even more versatility in creating
features for your shopping cart.
<P>
The catalog is read into an associative array called <TT><FONT FACE="Courier">iteminfo</FONT></TT>.
Each element of <TT><FONT FACE="Courier">iteminfo</FONT></TT>
is a description of the product followed by the price-for example,
<TT><FONT FACE="Courier">$iteminfo{T} = &quot;I Love CGI Programming
Unleashed&quot; T-Shirt@19.95</FONT></TT>. The following code
segment shows an example of how to read a file (catalog.txt) into
a two-dimensional array. Notice the use of the angle brackets
<TT><FONT FACE="Courier">&lt;&gt;</FONT></TT> within the <TT><FONT FACE="Courier">while
</FONT></TT>statement. The while loop will cycle through each
line of each file in <TT><FONT FACE="Courier">PRODUCTS</FONT></TT>.
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$filename = &quot;catalog.txt&quot;;
<BR>
open (PRODUCTS, $filename);<BR>
while (&lt;PRODUCTS&gt;) {<BR>
 ($type, $code, $name, $price) = split (/\t/);<BR>
 $iteminfo{$type, $code} = &quot;$name\@$price&quot;;<BR>
 }</FONT></TT>
</BLOCKQUOTE>

<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Perl does not directly support multidimensional arrays, but it doesn't really matter because Perl emulates the support of multidimensional arrays flawlessly. The line</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$iteminfo{$type, $code} = &quot;$name\@$price&quot;;<BR>
is a shorthand method for<BR>
$iteminfo {join ($;, $type, $code)} = &quot;$name\@price&quot;;</FONT></TT>
</BLOCKQUOTE>
<BLOCKQUOTE>
The special variable <TT><FONT FACE="Courier">$;</FONT></TT> is the subscript separator for multidimensional array emulation. The default value is ASCII 34, a nonprintable character, but it can be set to any value you want. If you want the substring 
separator to be the character <TT><FONT FACE="Courier">&quot;;&quot;</FONT></TT>, you can produce the following all-punctuation Perl line:
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$; = &quot;;&quot;;</FONT></TT>
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<H3><A NAME="UsingHiddenInputFieldstoMaintainSt">Using Hidden
Input Fields to Maintain State</A></H3>
<P>
The simplest means of tracking state within the shopping cart
CGI is through the use of hidden input fields in forms. The idea
is to record past additions to the cart and include them every
time the form is resubmitted.
<P>
The program in this chapter uses the subroutine <TT><FONT FACE="Courier">makehidden</FONT></TT>
to write the hidden input types. In order to distinguish items
previously added to the cart, the item variable names are &quot;pre-pended&quot;
with the word <TT><FONT FACE="Courier">old</FONT></TT>. Here's
the <TT><FONT FACE="Courier">makehidden</FONT></TT> subroutine.
<BLOCKQUOTE>
<TT><FONT FACE="Courier">sub makehidden {<BR>
foreach (sort keys %input) {<BR>
($item, $variable) = $_ =~ /^(\w+);(\w+)/;<BR>
print &quot;&lt;INPUT TYPE=hidden NAME=\&quot;old$item $variable\&quot;
<BR>
VALUE=\&quot;$input{$_}\&quot;&gt;\n&quot; if ($input{$item, add}
eq &quot;on&quot;);<BR>
}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
Here's an example of the HTML generated by the <TT><FONT FACE="Courier">makehidden</FONT></TT>
subroutine:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">&lt;INPUT TYPE=hidden NAME=&quot;oldT
add&quot; VALUE=&quot;on&quot;&gt;<BR>
&lt;INPUT TYPE=hidden NAME=&quot;oldT qty&quot; VALUE=&quot;100&quot;&gt;
<BR>
&lt;INPUT TYPE=hidden NAME=&quot;oldkeychain add&quot; VALUE=&quot;on&quot;&gt;
<BR>
&lt;INPUT TYPE=hidden NAME=&quot;oldkeychain qty&quot; VALUE=&quot;60&quot;&gt;
<BR>
</FONT></TT>
</BLOCKQUOTE>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Caution</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
One possible problem with using hidden input fields is that they are not really all that hidden. Anyone can see the contents of the hidden field by looking at the source<FONT FACE="Function Bold">. </FONT>It's possible that a user can download the page 
through her browser, change hidden fields by hand, and then resubmit the page with the changed information-an incredible potential security risk if the proper precautions are not taken.
</BLOCKQUOTE>
<BLOCKQUOTE>
The simplest way to avoid the problem of someone trying to submit a form in which he has changed the elements of the hidden input fields is to verify the path that the form is submitted from and reject input from improper paths.</BLOCKQUOTE>
<BLOCKQUOTE>
Any time a form is submitted, the path that the form is submitted from is contained in the environment variable <TT><FONT FACE="Courier">PATH</FONT></TT>.
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<H2><A NAME="OtherWaysofKeepingTrackofState"><FONT SIZE=5 COLOR=#FF0000>Other
Ways of Keeping Track of State</FONT></A></H2>
<P>
Although using hidden input is certainly a simple way of maintaining
state, it is not the only or even the best way to do so. Here
I will outline some of the most common methods used today for
maintaining state.
<H3><A NAME="htaccessandREMOTE_USER"><TT><FONT SIZE=4 FACE="Courier">htaccess</FONT></TT><FONT SIZE=4>
and </FONT><TT><FONT SIZE=4 FACE="Courier">REMOTE_USER</FONT></TT></A>
</H3>
<P>
One solution to the problem of identifying and remembering your
customers is through the use of password-protected areas. Users
are required to identify themselves as they enter. Thereafter,
they carry their identification with them. The standard on the
Internet for doing this is to protect your directories using the
<TT><FONT FACE="Courier">htaccess</FONT></TT> protocols found
in most of the common Web servers run today.
<P>
Anyone who has devoted time to surfing the Web will be familiar
with the pop-up boxes that ask you to enter your username and
password before entering a secured or private area. These pop-up
boxes appear any time a directory is accessed that has an <TT><FONT FACE="Courier">.htaccess</FONT></TT>
file in it. Listing 23.2 shows the Basic format of the <TT><FONT FACE="Courier">.htaccess</FONT></TT>
file, and Listing 23.3 shows a sample password file.<BR>
<HR>
<BLOCKQUOTE>
<B>Listing 23.2. Sample </B><TT><B><FONT FACE="Courier">.</FONT></B></TT><B><FONT SIZE=2 FACE="MCPdigital-B">htaccess</FONT>
file.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">AuthUserFile&nbsp;&nbsp;/usr/local/etc/httpd/secure/.htpasswd
<BR>
AuthGroupFile /usr/local/etc/httpd/secure/.htgroup<BR>
AuthName CGI Unleashed<BR>
AuthType Basic<BR>
<BR>
&lt;Limit GET&gt;<BR>
require group users<BR>
&lt;/Limit&gt;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
<HR>
<BLOCKQUOTE>
<B>Listing 23.3. Sample <FONT SIZE=2 FACE="MCPdigital-B">.htpasswd</FONT>
file.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">admin:qA/YMMCtFfBqk<BR>
anadas:hzUyvHrqk.JTw<BR>
erica:69ZUiJhiMnnLw<BR>
dave:D.Q6DFMVLIKIo<BR>
guest:..ZkwGDiWjEEs</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">.htusers</FONT></TT> file is usually
very simple:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">users: admin anadas dave erica guest</FONT></TT>
</BLOCKQUOTE>
<P>
The easiest way to add new passwords to the <TT><FONT FACE="Courier">.htpasswd</FONT></TT>
file is through using the program <TT><FONT FACE="Courier">htpasswd</FONT></TT>,
which is usually found in the same directory as the Web server
itself. You can, however, add users and passwords through a Perl
script using the <TT><FONT FACE="Courier">crypt</FONT></TT> function.
<P>
In this example the user's password as it is typed in is in <TT><FONT FACE="Courier">$input{passowrd}</FONT></TT>
and the login name is <TT><FONT FACE="Courier">$input{login}.</FONT></TT>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$salt = pack(&quot;HH&quot;,$input{login});
<BR>
$pass = crypt($input{password}, $salt);<BR>
open (PASSES, &quot;&gt;&gt;secure/.htpasswd&quot;);<BR>
print PASSES &quot;$input{login}:$pass\n&quot;;<BR>
close (PASSES);</FONT></TT>
</BLOCKQUOTE>
<P>
Once identification has been verified, the username entered in
the pop-up box is carried in the environment variable <TT><FONT FACE="Courier">REMOTE_USER</FONT></TT>.
<H3><A NAME="SessionIDEmbedding">Session ID Embedding</A></H3>
<P>
At many places on the Internet, you might notice very long and
strange looking URLs, often with a sequence of number and letters
in the middle. In these cases, it's likely that information about
the current state is maintained through session ID embedding.
<P>
Session ID embedding assigns a unique identifier to each customer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -