深入PHP购物车模块功能分析(函数讲解,附源码)


Posted in PHP onJune 25, 2013

一,购物车概述
购物车是为消费者在网上购物中提供一个临时存储商品的地方。其主要功能包括:添加商品、删除商品、更改商品数量、商品金额小计、商品金额总计和清空购物车;还包括生成订单、订单打印、订单预览、提交订单和取消购物等。
购物车的操作流程:首先,登录到网站中浏览商品;然后,购买指定的商品,进入购物车页面中,在该页面可以实现更改商品数量、删除商品、清空购物车、继续购物等;最后,填写收货人信息,生成订单,订单打印、预览,提交订单等操作。

二,热点关键技术
1,Smarty模块的安装配置
smarty是一个使用PHP写出来的PHP模板引擎,它将一个应用程序分成两部分实现:视图和逻辑控制。即将UI和PHP代码分离。PHP没有内置Smarty模板类,需要单独下载和配置,而且Smarty要求服务器上PHP版本最低为4.0.6。PHP Smarty可以在http://www.smarty.net/download下载。将压缩包解压,其中有一个libs目录,包含Smarty类库的所有核心文件。包括smarty.class.php、smarty_Compiler.class.php、config_File.class.php和debug.tpl 4个文件,还有internals和plug-ins两个目录。
复制libs目录到服务器根目录下,并重命名。这里将libs目录重新命名为smarty。到此Smarty模板安装完毕。
2,Smarty模板的配置
(1)首先确定Smarty目录的位置。因为Smarty类库是通用的,每一个项目基本都会使用,为了调用方便,习惯将smarty放置在根目录下。

(2)新建4个目录templates、templates_c、configs和cache,用于存储不同的文件。新建的4个目录位置是可以选择的,只要配置文件路径设置正确就可以了。

(3)创建配置文件。只要应用Smarty模板,那么就一定要包含Smarty类库和相关信息。每个页面都写一遍配置是不现实的,最好的方法就是将这些配置信息都写到一个文件中,通过include来调用配置文件。配置文件创建完成后保存在根目录下。本模块配置文件config.php代码如下:

<?php
 /*  定义服务器的绝对路径  */
 define('BASE_PATH','E:\PHPservices\\');
 /*  定义Smarty目录的绝地你路径  */
 define('SMARTY_PATH','SourceCode\12\01\\');
 /*  加载Smarty类库文件  */
 require BASE_PATH.SMARTY_PATH.'smarty\Smarty.class.php';
 /*  实例化一个Smarty对象  */
 $smarty = new Smarty;
 /*  定义各个目录的路径 */
 $smarty->template_dir = BASE_PATH.SMARTY_PATH.'./';
 $smarty->compile_dir = BASE_PATH.SMARTY_PATH.'templates_c/';
 $smarty->config_dir = BASE_PATH.SMARTY_PATH.'configs/';
 $smarty->cache_dir = BASE_PATH.SMARTY_PATH.'cache/';
 /*  定义定界符  */
 $smarty->left_delimiter = '<{';
 $smarty->right_delimiter = '}>';
 /*  使用Smarty赋值方法将一对儿名称/方法发送到模板中  */
?>

3,smarty模板动静分离
smarty模板最大的特点就是实现应用程序的动静分离,即将UI和PHP代码分离。下面介绍Smarty模板在实现动静分离的过程中常用的技术。
(1)在UI中获取PHP代码中模板变量的值
首先要确定Smarty模板的界定符,这里使用的是'<{'和'}>'。另外还应用到一些Smarty的内建函数section、php、if、elseif、else等。
a)section函数用于遍历数组中的数据。每个{section}标签必须与闭合标签{/section}成对出现,参数name和loop为必选项。
名称name是包含字母、数字和下划线的任意组合,可以嵌套但必须保证嵌套的name唯一。
变量loop(通常是数组)决定循环执行的次数,例如需要在section循环内输出变量时,必须在变量后加上中括号,中括号内包含name变量。
例如:
<{section name=data  loop=$myrow }>
 <tr>
  <td width="125" bgcolor="#FFFFFF"><{$myrow[data].tb_commodity_name}></td>
  <td bgcolor="#FFFFFF"><{$myrow[data].tb_commodity_price}></td>
 </tr>
<{/section}>b)php标签的作用是直接在模板中嵌入PHP脚本,标签的格式是"<{php}>"和"<{/php}>".
c)在Smarty的模板中同样也支持if、else语句,而且还增加了几个特性以适应模板引擎。if与/if必须成对出现;可以使用else和elseif字句;可使用以下条件修饰词:eq、ne、neq、gt、lt、lte、le、gte、ge、is even、is odd、is not even、is not odd、not、mod、div by、even by、odd by、===、!=、>、<、<=、>=。在使用修饰词时必须和变量或者常量用空格分隔开来。示例如下:
<{if $isShow=="F" }>
 <tr>
        <td height="22" colspan="5" bgcolor="#FFFFFF"><div align="center">对不起,您的购物车中暂无商品信息!</div></td>
    </tr>
<{else}>
 <{section name=data loop=$myrow }>
  <tr>
   <td height="22" align="center" bgcolor="#FFFFFF"><{$myrow[data].tb_commodity_name}></td>
   <td height="22" bgcolor="#FFFFFF"><div align="center"><{$myrow[data].tb_commodity_price}></div></td>
  </tr>
 <{/section}>
<{/if}>

(2)在PHP代码中定义模板变量,为模板变量赋值
UI中的数据是来自于PHP代码中定义的模板变量。在PHP代码中,完成PHP代码的编写,将要输出的值赋给一个模板变量,最后制定模板页进行输出。
a)为模板变量赋值通过自定义函数assign()来完成,其中第一个参数是被赋值的变量名,第二个参数是赋给变量的值。应用assign()函数的关键代码如下:
$smarty->assign("myrow",$array); //通过assign方法将数组$array中的数据写入到myrow中b)模板页的指定是通过display方法来完成的,其语法如下:
void display(string template[,string cache_id[,string compile_id]])
该方法用于指定模板页,其中第一个必选参数是指定一个合法模板资源的类型和路径;第2个可选参数指定一个缓存号;第3个可选参数指定一个编译号,再把一个模板编译成不同版本时使用。display方法应用的关键代码如下:
$smarty->display("index.tpl"); //指定要输出的模板页3,Session购物车的创建
Session购物车主要应用Session变量来实现。而所谓的购物车就是通过session_register()函数创建的2个Session变量;其中goodsid存储商品的ID,goodsnum存储商品的数量。Session购物车创建的代码如下:
<?php 
 session_start();  //初始化session变量
 session_register("goodsid"); //定义session变量用于存储商品ID
 session_register("goodsnum"); //定义session变量用于存储购买商品的数量
?>

session_register()函数,在整个域范围内增加一个Session变量。语法:boolean session_register(string name);
参数name用于指定新Session变量的名称。
4,通过数组函数判断购物车是否存在指定商品
为了避免在购物车中出现商品的重复添加,要对添加的商品与购物车中存储的商品进行判断。
a)应用explode()函数,将goodsid变量中存储的字符串以@为分隔符转换到数组中。
explode()函数,返回由字符串组成的数组,其中的每个元素都是由separator作为边界点分割出来的子字符串。
语法:array explode(string separator,string string,[ing limit])
参数说明:
separator:必须,规定在哪里分割字符串。不能为空字符串,否则explode()返回FALSE
string:必须,要分割的字符串。limit:可选,规定所返回的数组元素的最大数目。如果设置了limit参数,则返回的数组包含最多limit个元素,而最后那个元素将包含string的剩余部分。如果limit参数是负数,则返回除了最后的-limit个元素之外的所有元素。

b)in_array()函数判断数组中是否存在指定的商品ID,如果存在,则说明商品已经在购物车中;否则商品不存在,则将商品的ID添加到购物车中。

in_inarray()函数在数组中搜索给定的值。如果找到则返回True,否则返回False。
语法:bool in_array(mixed value,array array[,bool type])
参数说明:
value:必须,规定要在数组中搜索的值
array:必须,规定要搜索的数组。
type:可选,如果设置为true,则检查搜索的数据与数组的类型是否相同。
在购物车模块中,判断购物车中是否存在指定的商品的代码如下:

<?php 
 session_start(); //初始化session变量
 session_register("goodsid"); //定义session变量用于存储商品ID
 session_register("goodsnum"); //定义session变量用于存储购买商品的数量
 if($_SESSION["goodsid"]=="" && $_SESSION["goodsnum"]==""){ //判断session变量是否为空
  $_SESSION["goodsid"]=$_GET["id"]."@"; //如果session变量为空,则为其赋值为商品的ID,并以@分隔
  $_SESSION["goodsnum"]="1@";  //如果session变量为空,则为其赋值为1,并以@分隔
 }else{ //如果session变量不为空
   $array=explode("@",$_SESSION["goodsid"]); //则以@为分隔符,将session变量中的数据写入到数组中
   if(in_array($_GET["id"],$array)){ //如果判读数组中是否存在指定的ID
     echo "<script>alert('该商品已经被放入购物车!');history.back();</script>";
     exit;
   }
  //如果数组中不存在指定的ID,则说明该商品还没有放入购物车中
  $_SESSION["goodsid"].=$_GET["id"]."@"; //将该商品添加到购物车中
  $_SESSION["goodsnum"].="1@"; //更改商品数量
 }
 echo "<script>window.location.href='shopping_car.php';</script>";
?>

5,验证输入商品数量值是否有效
在preg_match()函数中,判断提交的商品数量的值是否符合正则表达式的标准,如果符合则有效,否则将给出提示信息。程序关键代码如下:
$id=$_POST["id"];       //获取商品id
$num=$_POST["goodsnum"];     //获取商品数量
$preg="/^[0-9]*[0-9]$|^[0-9]*[0-9]$/";  //编写正则表达式
if($num==""){        //判断提交的值是否为空
 echo "<script>alert('数量不能为空!');history.back();</script>";
 exit;
}else if(!preg_match($preg,$num,$str)){  //判断提交的数据是否是正整数
  echo "<script>alert('数量只能为正整数!');history.back();</script>";
  exit;
}

preg_match()函数,在字符串中搜索所有与给出的正则表达式匹配的内容,如果存在则返回True,否则返回False。语法如下:
语法:int preg_match(string pattern,string sbuject[,array matches[,int flags]])
参数说明:
pattern:必要参数,需要匹配的正则表达式
subject:必要参数,输入的字符串matches:可选参数。输出的搜索结果的数组,例如$out[0]将包含与整个模式匹配的结果,$out[1]将包含与第一个捕获的括号中的子模式所匹配的结果,一次类推
flags:可选参数,标记:PREG_OFFSET_CAPTURE,对每个出现的匹配结果页同时返回共附属的字符串偏移量

三,函数实现过程
1,添加商品功能
添加商品功能的实现原理是:首先创建一个购物车,然后以商品展示页中“购买”链接传递的商品ID($_GET[id])为依据,向购物车中添加商品(商品ID),并且不允许重复添加。向购物车中添加商品的操作通过by_commodity.php文件来完成。
首先,创建一个购物车。
然后,判断购物车中是否为空,如果为空,则将商品的ID和数量添加到购物车中;如果不为空,则要判断添加商品的ID是否在购物车中已经存在,如果存在则不能重复添加,否则将商品ID添加到购物车中。
添加商品程序代码如下:

<?php
 header("Content-type:text/html;charset= utf-8");
 session_start();  //初始化session变量
 session_register("goodsid"); //定义session变量用于存储商品ID
 session_register("goodsnum"); //定义session变量用于存储购买商品的数量
 if($_SESSION["goodsid"]=="" && $_SESSION["goodsnum"]==""){  //判断session变量是否为空
  $_SESSION["goodsid"]=$_GET["id"]."@";      //如果session变量为空,则为其赋值为商品的ID,并以@分隔
  $_SESSION["goodsnum"]="1@";      //如果session变量为空,则为其赋值为1,并以@分隔
 }else{            //如果session变量不为空
   $array=explode("@",$_SESSION["goodsid"]);  //则以@为分隔符,将session变量中的数据写入到数组中
   if(in_array($_GET["id"],$array)){    //如果判读数组中是否存在指定的ID
     echo "<script>alert('该商品已经被放入购物车!');history.back();</script>";
     exit;
   }
  //如果数组中不存在指定的ID,则说明该商品还没有放入购物车中
  $_SESSION["goodsid"].=$_GET["id"]."@";   //将该商品添加到购物车中
  $_SESSION["goodsnum"].="1@";     //更改商品数量
 }
 echo "<script>window.location.href='shopping_car.php';</script>";
?>

2,删除购物车中商品功能的实现
删除购物车中商品的操作是根据“删除该项”超级链接中传递的商品ID($_GET[id])执行的。在delete_commodity.php文件中,根据$_GET[id]传递的值,执行删除购物车中商品的操作。
首先,获取$_GET[id]传递的值。然后,应用explode()函数,将Session变量中存储的商品ID和数量的数据写入数组,并以@作为分隔符。
接着,应用array_search()函数,获取数组中指定ID商品的键名,并根据获取的键名将数组中指定的数据赋值为空。
最后,将数组中重新赋值的空数据写入购物车中,从而完成删除购物车中指定商品的操作。
<?php
 session_start();    //初始化session变量
 require("config.php");   //连接smarty模板
 $id=$_GET["id"];    //获取要删除商品的ID
 $arrayid=explode("@",$_SESSION["goodsid"]);  //将购物车中存储的商品ID的字符串转换到数组中
 $arraynum=explode("@",$_SESSION["goodsnum"]); //将购物车中存储的商品数量的字符串转换到数组中
 $key=array_search($id,$arrayid);    //获取到数组中指定的数据,并返回键名
 $arrayid[$key]="";        //根据返回的键名,将数组中的数据赋值为空
 $arraynum[$key]="";        //根据返回的键名,将数组中的数据赋值为空
 $_SESSION["goodsid"]=implode("@",$arrayid);  //重新将数组中的数据添加到购物车中
 $_SESSION["goodsnum"]=implode("@",$arraynum); //重新将数组中的数据添加到购物车中
 echo "<script>window.location.href='shopping_car.php';</script>";
 $smarty->display("shopping_car.tpl");
?>

删除前$_SESSION["goodsid"]的值为"3@2@5@",删除$id=5后$_SESSION["goodsid"]的值为"3@2@@";这样Session中存在多余的数据@。
解决方法:
<?php
 session_register("goods"); //创建session数组
 $id=$_GET['id'];
 $arraygoods=$_SESSION["goods"];
 if($_SESSION["goods"]==""){
  $_SESSION["goods"][$id]="$id,1"; //根据商品ID保存商品,键名为$id,键值为$id,1(商品ID和购买商品数量,默认购买数量为1)
 }else{
  if(array_key_exists($id,$_SESSION["goods"])){
    echo "<script>alert('该商品已经被放入购物车!');history.back();</script>";
    exit;
  }
  $_SESSION["goods"][$id]="$id,1";
 }
?>

商品信息以数组形式保存,[4] => 4,4。键名为商品ID,值为键名和购买商品数量。添加删除商品只需要根据ID号找到对应商品修改信息即可。
Array
(
    [4] => 4,4
    [3] => 3,5
    [1] => 1,10
    [2] => 2,1
)

3,生成订单功能的实现
生成订单功能就是从数据库中读取出填写的订单信息,对其内容进行重新整合,形成一个订单模式,并且实现订单打印和订单预览的功能。订单生成的操作通过两个文件来完成,一个是从数据库中读取数据,将所需的数据赋值给指定的Smarty模板变量,并指定模板页。
<?php 
 session_start();
 header("Content-type:text/html;charset= utf-8");
 require_once("conn.php");
 require_once("config.php");
 $array=array();        //定义一个空数组
 $ddnumber=base64_decode($_GET["ddno"]);
 mysql_query("set names utf8");
 $sql=mysql_query("select * from tb_commodity_order_form where ddnumber='".$ddnumber."'",$conn);
 $info=mysql_fetch_array($sql);
 array_push($array,$info);    //将获取的数组值写入到新的数组中
 $smarty->assign("info",$array);
 $array=explode("@",$info["spc"]);
 $arraynum=explode("@",$info["slc"]);
 $totalprice=0;         //定义价格变量
 $arrayinfo=array();        //创建数组
 for($i=0;$i<count($array);$i++){
  if($array[$i]!=""){
   $sqlcart=mysql_query("select * from tb_commodity where tb_commodity_id='".$array[$i]."'",$conn);
   $infocart=mysql_fetch_array($sqlcart); //读取数据库中数据
   $totalprices=$infocart["tb_commodity_price"]*$arraynum["$i"];  //计算总的价格
   array_push($infocart,$arraynum["$i"]);  //将购买数量的数据写入到数据库中返回的数组中    
   array_push($infocart,$totalprices);  //将购买数量的数据写入到数据库中返回的数组中    
   array_push($arrayinfo,$infocart);       //将整理的数据压入到创建的新数组中
   $totalprice+=$infocart["tb_commodity_price"]*$arraynum["$i"];  //计算总的价格
  }
 }
 session_unregister("goods");
 if(count($arrayinfo)>0){      //判断数组是否为空
  $gnum=count($arrayinfo);
  $smarty->assign("isShow","T");
  $smarty->assign("gnum",$gnum);
  $smarty->assign("myrow",$arrayinfo);
  $smarty->assign("totalprice",$totalprice);
 }else{
  $smarty->assign("isShow","F");
 }
 $smarty->display("shopping_dd.tpl");
?>

另一个是shopping_dd.tpl模板页,输出模板变量中存储的数据,生成一个订单。

四,源代码下载:点击下载

PHP 相关文章推荐
Email+URL的判断和自动转换函数
Oct 09 PHP
基于PHP的cURL快速入门教程 (小偷采集程序)
Jun 02 PHP
PHP转换文件夹下所有文件编码的实现代码
Jun 06 PHP
CodeIgniter图像处理类的深入解析
Jun 17 PHP
php实现与erlang的二进制通讯实例解析
Jul 23 PHP
php实现paypal 授权登录
May 28 PHP
php链表用法实例分析
Jul 09 PHP
PHP上传文件参考配置大文件上传
Dec 16 PHP
PHP实现一个简单url路由功能实例
Nov 05 PHP
ZendFramework框架实现连接两个或多个数据库的方法
Dec 08 PHP
PHP实现限制IP访问及提交次数的方法详解
Jul 17 PHP
PHP执行普通shell命令流程解析
Aug 24 PHP
基于PHP+Ajax实现表单验证的详解
Jun 25 #PHP
PHP Class&amp;Object -- 解析PHP实现二叉树
Jun 25 #PHP
PHP Class&amp;Object -- PHP 自排序二叉树的深入解析
Jun 25 #PHP
通过PHP current函数获取未知字符键名数组第一个元素的值
Jun 24 #PHP
PHP多例模式介绍
Jun 24 #PHP
PHP获取和操作配置文件php.ini的几个函数介绍
Jun 24 #PHP
PHP垃圾回收机制引用计数器概念分析
Jun 24 #PHP
You might like
使用ob系列函数实现PHP网站页面静态化
2014/08/13 PHP
[原创]ThinkPHP让../Public在模板不解析(直接输出)的方法
2015/10/09 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
浅谈PHP匿名函数和闭包
2019/03/08 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
2019/04/10 PHP
什么是json和jsonp,jQuery json实例详详细说明
2012/12/11 Javascript
javascript unicode与GBK2312(中文)编码转换方法
2013/11/14 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
2016/05/04 Javascript
浅析js的模块化编写 require.js
2016/12/07 Javascript
JavaScript中的call和apply的用途以及区别
2017/01/11 Javascript
微信小程序提交form操作示例
2018/12/30 Javascript
微信小程序实现卡片左右滑动效果的示例代码
2019/05/01 Javascript
[06:23]2014DOTA2西雅图国际邀请赛 小组赛7月12日TOPPLAY
2014/07/12 DOTA
Python入门篇之数字
2014/10/20 Python
Python实现简单字典树的方法
2016/04/29 Python
Python实现定时任务
2017/02/08 Python
python编写Logistic逻辑回归
2020/12/30 Python
利用python将xml文件解析成html文件的实现方法
2017/12/22 Python
python itchat实现调用微信接口的第三方模块方法
2019/06/11 Python
Django 对象关系映射(ORM)源码详解
2019/08/06 Python
Keras 加载已经训练好的模型进行预测操作
2020/06/17 Python
css3实现图片遮罩效果鼠标hover以后出现文字
2013/11/05 HTML / CSS
HTML5的结构和语义(5):交互
2008/10/17 HTML / CSS
浅析HTML5中的download属性使用
2019/03/13 HTML / CSS
Speedo澳大利亚官网:全球领先游泳品牌
2018/02/04 全球购物
英国最大的宝石首饰超市:QP Jewellers
2018/09/23 全球购物
交通事故调解协议书
2014/04/16 职场文书
操行评语大全
2014/04/30 职场文书
个人批评与自我批评发言稿
2014/09/28 职场文书
六年级情感作文之500字
2019/10/23 职场文书
如何用PHP实现多线程编程
2021/05/26 PHP
Mysql 如何查询时间段交集
2021/06/08 MySQL
Pygame Event事件模块的详细示例
2021/11/17 Python
Windows server 2012搭建FTP服务器
2022/04/29 Servers