创建购物车程序
更新时间:2024-01-23 05:59:01 阅读量: 教育文库 文档下载
第6章 创建购物车程序
第6章
创建购物车程序
Creating a Shopping Cart
对于许多Web开发者来说,简陋的购物车程序在他们心目中有着特殊的位置。虽然许多Web应用程序都是用PHP和MySQL写成,但很多开发者都是从一个无所不在的购物车程序开始其职业生涯的。如果说Web开发蕴含着禅意,那么也许只有在编写购物车时才能体验到这种意境。
放眼互联网,购物车千姿百态,各有不同。众多购物车形态之间的差异是由各自针对的业务不同而造成的。例如,卖书、CD和DVD的购物车与卖电缆、食物、建材和清洁用品的购物车就截然不同。主要区别在于数量,用户通常一次只买一本书或一张DVD,但餐馆一次性购买10袋面包却是家常便饭。 6.1 项目概述
本项目将创建购物车的核心功能。为使您对项目有个清晰的认识,先来看看下面的例子。 John想为他的汽车咖啡店买些茶包。于是他访问了一个知名的在线商店,商店的主人就是本书的一名读者。John没有该网站的用户账号,但他依然开始了购物。他点击了“饮料”分类,看到了茶包的列表。在点击“购买”链接后,系统跳到了另一个页面,在该页面上可以选择数量。他选择了10箱茶包,并将其放到购物车里。随后,页面刷新,他看到了购物车里的内容。接下来John又买了咖啡,于是购物车再次更新。但John想起他不需要咖啡,便点击了“×”(删除)链接,从购物车中删掉了咖啡。John选完了商品,点击了“去收银台”链接。系统提示他输入自己的地址,输入之后他被带到了付款界面。在那里,他可以选择通过PayPal[7]或支票付款。John点击了PayPal按钮,系统跳到了位于paypal.com的PayPal付款界面,John为自己的订单付了款。
Pauline也想买些茶包。不过她已经有了自己的账户,所以她首先登录。然后把自己想要的东西放到了购物车中,再单击了“去收银台”链接。在地址输入页面中,可以选择输入新地址,或者使用账户中保存的地址。她选择了账户保存的地址后跳转到付款界面。Pauline选择了用支票付款,系统告诉她应当向哪里、向谁发送支票。 Ken是网站的运营者,他想查看当前的所有订单。于是他用自己的管理员用户名和密码登录,登录后看到了一系列的订单。Ken逐一查看每一项商品,然后为订单打包货物,并在包裹上写好地址。最后Ken点击了“确认付款”链接,确认该订单完成。整个订单的处理流程至此结束。
本章中建立的购物车将满足前面例子中讨论的所有特性,但实际上仍有无数功能可继续开发。购物车可以成为巨大而复杂的系统,说句公道话,用一整本书来讨论购物车构建的话题都不为过。本项目只是为您继续开发其他特性打下一个坚实的基础。
6.2 建立数据库
本项目使用的数据库如图6-1所示。
图6-1 所有数据库结构均围绕着主要的orders表
从根本上讲,整个项目都依赖于orders表中存储的各个订单。该表关联着customers表(包含的是注册用户的地址详细信息)和delivery_addresses(包含的是未注册用户的地址和注册用户的其他地址)表。订单中的每件商品(存储于products表中)都保存在orderitems表中。其他的表包括logins(存储着注册用户的登录信息),categories(包含的是产品所属的类别)和admins表(存储着管理员登录信息)。 6.2.1 实现数据库
启动phpMyAdmin,新建一个名为shoppingcart的数据库,然后添加以下各表:
NOTE
始终要记住订单的状态
orders表中有个字段叫做status。该字段的作用是标明在购物过程中用户已经进行到了哪个阶段。该字段有4个可能的值: 0 用户仍在向购物车中添加商品; 1 用户已经输入了地址; 2 用户已经付款;
10 管理员已经确认了交易并发送了商品。
admins表
n id:将其设为TINYINT类型(管理员不会太多)并打开auto_increment。设置该字段为主键。
n username:将其设为VARCHAR类型,长度为10。 n password:将其设为VARCHAR类型,长度为10。 categories表
n id:将其设为TINYINT类型(类别数目不会太多),并打开Extras列中的auto_increment。设置该字段为主键。
n name:将其设为VARCHAR类型,并将长度设置为20。(类别标题一般不会超过20个字符。) customers表
n id:将其设为INT类型(会有很多用户)并打开auto_increment。设置该字段为主键。
n forename:将其设为VARCHAR类型,长度为50。 n surname:将其设为VARCHAR类型,长度为50。 n add1:将其设为VARCHAR类型,长度为50。 n add2:将其设为VARCHAR类型,长度为50。 n add3:将其设为VARCHAR类型,长度为50。 n postcode:将其设为VARCHAR类型,长度为10。 n phone:将其设为VARCHAR类型,长度为20。 n email:将其设为VARCHAR类型,长度为100。
n registered:将其设为TINYINT类型。 delivery_addresses表
n id:将其设为INT类型(用户有很多)并打开auto_increment。设置该字段为主键。 n forename:将其设为VARCHAR类型,长度为50。 n surname:将其设为VARCHAR类型,长度为50。 n add1:将其设为VARCHAR类型,长度为50。 n add2:将其设为VARCHAR类型,长度为50。 n add3:将其设为VARCHAR类型,长度为50。 n postcode:将其设为VARCHAR类型,长度为10。 n phone:将其设为VARCHAR类型,长度为20。 n email:将其设为VARCHAR类型,长度为100。 logins表
n id:将其设为INT类型(用户有很多)并打开auto_increment。设置该字段为主键。 n customer_id:类型为INT。
n username:将其设为VARCHAR类型,长度为10。 n password:将其设为VARCHAR类型,长度为10。 orderitems表
n id:将其设为INT类型(订购商品会有很多)并打开auto_increment。设置该字段为主键。
n order_id:将其设为INT类型。 n product_id:将其设为INT类型。 n quantity:将其设为INT类型。 orders表
n id:将其设为INT类型(订单会有很多)并打开auto_increment。设置该字段为主键。
n customer_id:将其设为INT类型。 n registered:将其设为INT类型。
n delivery_add_id:将其设为INT类型。 n payment_type:将其设为INT类型。 n date:将其设为DATETIME类型。 n status:将其设为TINYINT类型。
n session:将其设为VARCHAR类型,长度为50。 n total:将其设为FLOAT类型。 products表
n id:将其设为INT类型(商品会有很多)并打开auto_increment。设置该字段为主键。
n cat_id:将其设为TINYINT类型。
n name:将其设为VARCHAR类型,设置长度为100。有的产品名会很长。 n description:将其设为TEXT类型。
n image:将其设为VARCHAR类型,长度为30。 n price:将其设为FLOAT类型。
6.2.2 插入样本数据 建好这一整套数据库表之后,接下来应该添加一些样本数据。记住不要填写id列,auto_increment会自动处理它。可以随意添加自己的样本数据,也可以使用下面推荐的信息。 admins表的样本数据 为管理员创建用户名和密码。本例中使用的用户名为jono,密码为bacon。 categories表的样本数据 添加两个类别:beverages和cakes。 customers表的样本数据 按照表6-1添加客户。 表6-1 customers和logins表存储的是注册用户的详细信息 ForenaSurnaAdd1 Add2 Add3 me me Postal Phone Code E-mail Registered 19, ZiggTuckeSmalltoT3 Craig The y r wn TR4 Grove Road 19, JordaOak BootThistowT1 n Streeh n Road FG3 t 012345678hissite.c1 90 om 012340987tastic.co1 65 m craig@ lee@lee Lee logins表的样本数据 为每个客户添加表6-2 所示的登录信息。 表6-2 请确保customer_id字段能匹配customers表中的id字段 Customer_id 1 2 Username Craig Lee Password Tucker Jordan delivery_addresses表的样本数据 保持该表为空。 products表的样本数据 向products表中添加如表6-3所示的商品。 表6-3 如果存在图片,则用image字段保存图片名 Cat_id Name 1 Best Bags Description Image A quality pack of
1 Best Orange Juice One gallon of quality squeezed orange juice. bestorange-juice.jpg 0.90 orders表的样本数据 保持该表为空。 orderitems表的样本数据 保持该表为空。
6.3 开始编码
创建购物车程序的一个挑战是需要同时处理注册用户和未注册用户。对于注册用户完全没有问题,因为向表中添加信息时可以使用其ID对用户进行跟踪。而对于未注册用户则遇到了一个 难题。如何跟踪他们?
解决方案是使用会话ID(session ID)。用户加载第一页时,session_start()函数会生成一个特殊的会话ID。该ID对于特定用户来说是唯一的,用它可以跟踪访问网站的用户所使用的会话变量。虽然以前没有使用过会话ID,但在本项目中,我们将广泛使用它。
每当用户访问购物车程序并添加第一件商品时,系统就会将一个订单添加到orders表中。对于注册用户,用户的id会保存到该表的customer_id字段中。对于未注册用户,则在session字段中保存唯一的会话id。将订单添加到orders表中后,系统将使用订单的id创建一个名为SESS_ORDERNUM的会话变量。之后就可通过SESS_ORDERNUM来跟踪用户在整个网站中的购物过程了。
先来创建通用配置文件,它保存的是网站的一般性信息。建立名为shoppingcart的新目录,并将示例6-1的代码保存为config.php。
示例6-1 配置文件与本书其他项目中的配置文件大同小异
$dbhost = \$dbuser = \$dbpassword = \
$dbdatabase = \
$config_basedir = \$config_sitename = \?>
为使得重定向更容易处理,可将有关数据库连接的细节放到名为db.php的文件中,如示例6-2所示。 示例6-2 当需要数据库连接,但由于要重定向而不能包含header.php时,可以包含db.php文件
require(\
$db = mysql_connect($dbhost, $dbuser, $dbpassword); mysql_select_db($dbdatabase, $db); ?>
创建示例6-3所示的header.php。
示例6-3 页头文件负责添加菜单选项、侧边栏以及一些登录/注销链接
session_start();
if(isset($_SESSION['SESS_CHANGEID']) == TRUE) {
session_unset(); session_regenerate_id(); }
require(\
$db = mysql_connect($dbhost, $dbuser, $dbpassword); mysql_select_db($dbdatabase, $db); ?>
showcart.php\
require(\ echo \
if(isset($_SESSION['SESS_LOGGEDIN']) == TRUE) {
echo \ . \
[
echo \ }
?>
header.php中有些很有意思的地方,让我们来细细品味一下:
n 在文件开头,先检查会话变量SESS_CHANGEID是否存在。如果存在,则unset(删除)该变量,这样就会重新生成会话id。稍后当订单完成后,在需要重置会话系统时,将会创建SESS_CHANGEID变量。 n 检查SESS_LOGGEDIN变量是否存在。如果存在,则说明用户已经登录,于是显示用户名和“注销”链接。用户名存储在SESS_USERNAME中,该变量在稍后即将说明的login.php中创建。 n 本书以前项目中用到的stylesheet.css原封不动地用在这里。
页头文件中还包含了一个名为bar.php的文件。该文件含有示例6-4所示的分类列表。
示例6-4 虽然bar.php中的代码可以直接加到header.php中,但使用独立的文件可以在必要时整洁地添加其他内容
Product Categories
$catsql = \ $catres = mysql_query($catsql);
while($catrow = mysql_fetch_assoc($catres)) {
echo \ . \ . $catrow['name'] . \ } ?>
bar.php中的代码执行了一个SELECT查询以收集所有的分类信息,并将其显示为项目列表。每个分类均链接至即将创建的products.php中。
建立footer.php并添加示例6-5中所示的代码。
示例6-5 在管理员登录后,页脚文件会创建管理(“admin”)链接
echo \ . $config_sitename . \
if($_SESSION['SESS_ADMINLOGGEDIN'] == 1) {
echo \[
. \ } ?>