1. 程式人生 > >PHP 購物車 session (ThinkPHP)

PHP 購物車 session (ThinkPHP)

 本篇文章為ThinkPHP框架實現購物車,上一篇文章為非框架實現購物車


這是我的一次面試中的面試題,簡單寫商城的購物車功能,要求是:

1、自己寫簡單的前臺

2、使用者登入前能用購物車

3、不可以用cookie

暫時瞭解到的解決方法有三個:

1、cookie

2、session

3、資料庫

該購物車的主要邏輯是,用session來實現識別不同的使用者各自的購物車,以便使用者登入後儲存的是自己的購物車。流程圖如下:

ThinkPHP框架下,實現該購物車功能相對非框架的實現更加簡單快捷一些,主要是兩個控制器檔案分別是商品控制器GoodsContoller.class.php以及使用者控制器IndexControllerr.class.php

,以及三個檢視模板檔案分別是商品展示模板showlist.html 購物車內容模板shop_cart.html  登入介面模板login.html 至於資料表只需要建立三個,一個是使用者表user  一個是商品表 goods   最後一個是訂單表buy

GoodsController.class.php

<span style="font-size:12px;"><?php

namespace Home\Controller;

use Think\Controller;

Class GoodsController extends Controller {

    //展示商品內容的的方法
    public function showlist() {

        $goods = D('goods');
        $goods_list = $goods->order('goods_id desc')->select();


        $this->assign('goods_list', $goods_list);
        $this->display();
    }

    //展示已新增到購物車的商品的方法,把已新增的商品暫時存放在一組二維陣列陣列當中array(‘商品名字’ => array(商品資訊))
    public function shop_cart() {

        session_start();  //開啟session
        $GET_name = I('get.goods_name');
        $GET_id = I('get.goods_id');

        $shop_cart = I('session.shop_cart');  //讀取session並放在陣列$shop_cart
        //判斷session陣列中是否存在過該新增購物車的商品
        if (array_key_exists($GET_name, $shop_cart)) {
            //該商品已經新增過購物車,進行shop_cart陣列中的該商品數量加1的操作
            $shop_cart[$GET_name]['goods_num'] ++;
        } else {
            //該商品為新商品,進行資料庫查詢該商品具體資訊,並存入shop_cart陣列
            $goods = D('goods');
            $result = $goods->where(array('goods_id' => array('eq', $GET_id)))->select();

            $arr0 = array($GET_name => array('goods_id' => $GET_id, 'goods_num' => 1, 'goods_name' => $GET_name, 'goods_price' => $result[0]['goods_price']));

            foreach ($arr0 as $key => $value) {
                $shop_cart[$key] = $value;
            }
        }


        session('shop_cart', $shop_cart);  //賦值給session
        //var_dump($shop_cart);
        $this->assign('shop_cart', $shop_cart);
        $this->display();
    }

    //清空當前購物車的方法
    public function clean_cart() {
        session('shop_cart', null);
        redirect(U('showlist'), 2, '已成功清空購物車,正在跳轉到商城首頁。。。。。');
    }

    //結算方法
    public function finish() {
        //通過session['user_name']判斷是否登入。如果已登入則把資料寫入資料庫,並提示成功跳轉到商品展示頁
        //如果未登入 ,提示進行登入,並且跳轉至登入頁面
        session_start();  //開啟session
        $buy = D('buy');
        $shop_cart = session('shop_cart');  //從session中讀取購物車二維陣列
        $user_name = session('user_name');    //從session中讀取使用者的資訊

        if (isset($user_name)) {
            //已經登入,從session中取出資料來寫入資料庫
            foreach ($shop_cart as $v => $val) {

                $data['buy_goods_id'] = $val['goods_id'];
                $data['buy_goods_name'] = $val['goods_name'];
                $data['buy_goods_num'] = $val['goods_num'];
                $data['buy_goods_price'] = $val['goods_price'];
                $data['user_name'] = $user_name;

                $rs = $buy->add($data);
            }
            if ($rs)
                $this->success('結算成功!!!現在返回首頁', U('showlist'), 2);  //成功寫入資料則提示並2秒後跳轉
            else
                $this->error('結算失敗,正在返回購物車!!!', U('shop_cart'), 3); //失敗寫入資料則提示並3秒後跳轉
        }else {
            //未登入則重定向到登入頁面
            redirect(U('Index/login'), 2, '請登入後再進行結算,介面正跳轉到登入介面。。。');
        }
    }

}

?></span>

IndexController.class.php

<?php

namespace Home\Controller;

use Think\Controller;

class IndexController extends Controller {

    public function index() {
        $this ->display(U('Goods/showlist'));
    }

    public function login() {
        $this->display();
    }

    public function logout() {
        session('user_name', null);
        redirect(U('Goods/showlist'), 2, '已成功退出,正在返回商城首頁。。。。。');
    }

    public function check_login() {

        session_start(); //開啟session
        $user = D('user');

        $user_name = I('post.user_name');
        $user_pwd = I('post.user_pwd');


        //查詢資料庫,並先驗證使用者名稱是否正確,若正確再進行下一步驗證密碼
        $result = $user->where(array('user_name' => array('eq', $user_name)))->select();



        if ($result) {
            if ($result[0]['user_pwd'] == $user_pwd) {
                session('user_name', $user_name);  //把使用者名稱新增到session中
                redirect(U('Goods/showlist'), 1, '正在登入中。。。。');
            } else {
                redirect(U('login'), 2, '密碼錯誤!請重新登入。');
            }
        } else {
            redirect(U('login'), 2, '不存在該使用者,請重新登入。');
        }
    }

}

shoplist.html

<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        
        當前使用者:
        <a style="font-size: 150%;color: red;" >
        <?php 
            if(isset($_SESSION['user_name']))
                echo $_SESSION['user_name'] . "     ";
            else
                echo '未登入';
               
        ?>
        </a>
        
        <a style="font-size: 150%;color: #f0c040" href="__CONTROLLER__/showlist"  >繼續購物</a>
        </br>
        </br>
        <a style="font-size: 150%;color: blue" >購物車狀態:</a>
        <table border="1"  height="400px" width="400px">    
            <td style="font-size: 120%;color: blue;text-align: center">商品id</td>
            <td style="font-size: 120%;color: blue;text-align: center">商品名字</td>
            <td style="font-size: 120%;color: blue;text-align: center">商品數量</td>
            <td style="font-size: 120%;color: blue;text-align: center">商品價格</td>


        <volist name="shop_cart" id="val">
            <tr>
                <td width="50px"><?php echo $val['goods_id']?></td>
                <td ><?php echo $val['goods_name']?></td>
                <td ><?php echo $val['goods_num']?></td>
                <td ><?php echo $val['goods_price']?></td>
            </tr>
        </volist>

        </table>

        <form name="myform" method="POST" action="__CONTROLLER__/finish">

            <input type="hidden" name="goods_id" value=" $val['goods_id']" /><br/>

            <input type="hidden" name="goods_name" value="$val['goods_name']" /><br/>

            <input type="hidden" name="goods_num" value="$val['goods_num']" /><br/>

            <input type="hidden" name="goods_price" value="$val['goods_price']" />

            <input type="submit" name="sub" style="font-size: 200%;color: red" value="結算購物車" />
            <a href="__CONTROLLER__/clean_cart"><input type="button" value="清空購物車" style="font-size: 200%;color: red"></a>

        </form>

    </body>
</html>

shop_cart.html

<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        當前使用者:<a style="font-size: 150%;color: red" >
        <?php 
            if(isset($_SESSION['user_name'])){
             echo $_SESSION['user_name'];
         ?>
         <a href="__MODULE__/Index/logout">(退出登入)</a>
         <?php
               
            }else{
                echo '未登入';
              
        ?>
        <a href="__MODULE__/Index/login">(登入)</a>
        <?php }?>
        </a>
       
<a style="font-size: 150%;color: blue" href="__CONTROLLER__/shop_cart">購物車內容</a>
 </br></br>
 <a style="font-size: 150%;color: blue">商品列表:</a>
<table border="1"  height="400px" width="400px">    
    <td style="font-size: 120%;color: blue;text-align: center">商品id</td>
    <td style="font-size: 120%;color: blue;text-align: center">商品名字</td>
    <td style="font-size: 120%;color: blue;text-align: center">商品數量</td>
    <td style="font-size: 120%;color: blue;text-align: center">商品價格</td>
    <td style="font-size: 120%;color: blue;text-align: center">操作</td>

    <volist name="goods_list" id="v1">
    <tr>
        <td width="50px">{$v1.goods_id}</td>
        <td >{$v1.goods_name}</td>
        <td >{$v1.goods_num}</td>
        <td >{$v1.goods_price}</td>
        <td style="font_size:150%;color: red;text-align:center" >
            <a href="__CONTROLLER__/shop_cart?goods_name={$v1.goods_name}&goods_id={$v1.goods_id}">加入購物車
        </td>
    </tr>
    
    
</volist>
</table>

    </body>
</html>


login.html

<html>
<head>
<meta charset="utf-8"/>
<title>使用者登陸</title>
</head>
<body>
    <h1>請進行商城使用者登入:</h1>
<form name="myform" method="POST" action="__CONTROLLER__/check_login">

    使用者名稱:<input type="text" name="user_name" value="" /><br/>

    密碼  :<input type="password" name="user_pwd" value="" /><br/>

    <input type="submit" name="sub" value="使用者登陸" />

</form>
</body>
</html>


shoppingcart.sql(該檔案不是工具直接匯出,所以需要手動複製程式碼建立)

--shoppingCart.sql
--該檔案為記錄此商城所需要建立的資料庫的各種表以及資料
CREATE DATABASE `ShoppingCart`;
--Goods表
DROP TABLE IF EXISTS `Goods`;

    CREATE TABLE `Goods`(
    `goods_id` tinyint(4) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `goods_name` varchar(20) NOT NULL COMMENT '商品名字',
    `goods_num` smallint(6) unsigned NOT NULL  COMMENT '商品剩餘數量',
    `goods_Price` smallint(6)  unsigned NOT NULL COMMENT '商品價格'
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
--使用者表
DROP TABLE IF EXISTS `User`;
    CREATE TABLE `User`(
    `user_id` tinyint(4) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `user_name` varchar(20) NOT NULL COMMENT '使用者名稱',
    `user_pwd` varchar(20) NOT NULL COMMENT '使用者密碼'
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

--訂單表
CREATE TABLE `Buy`(
    `buy_goods_id` tinyint(4) unsigned NOT NULL ,
    `buy_goods_name` varchar(20) NOT NULL COMMENT '商品名字',
    `buy_goods_num` smallint(6) unsigned NOT NULL  COMMENT '商品購買數量',
    `buy_goods_Price` smallint(6)  unsigned NOT NULL COMMENT '商品價格',
    `user_name` varchar(20) NOT NULL COMMENT '訂單提交者'
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
--使用者表

insert into `Goods` values(1,'Nokia',100,2000);
insert into `Goods` values(2,'Samsung',150,3000);
insert into `Goods` values(3,'Apple',200,4000);


insert into `User` values(1,'Tim','123');
insert into `User`  values(2,'Jack','123');
insert into `User`  values(3,'Tom','123');


值得注意的是,因為該專案只是實現了購物車的功能,也沒有真正意義上的商城預設首頁,所以應該把配置檔案中的ThinkPHP預設控制器修改成GoodsController,以及預設操作修改成showlist。從而實現使用者開啟網站的首頁就是展示商品GoodsController/showlist。

'DEFAULT_CONTROLLER' => 'Goods', // 預設控制器名稱
'DEFAULT_ACTION' => 'showlist', // 預設操作名稱

總結:

其實購物車的邏輯很簡單,由於ThinkPHP框架先天優勢,MVC模式使得邏輯相對非框架更清晰明瞭。主要是解決如何識別每一個沒登入使用者的身份,這有三種方案解決,分別是1、cookie 2、session 3、資料庫 ;這一點用session就很容易解決,相對COOKIE的解決方案優點是不會因為使用者禁用了本機的cookie功能而導致購物車功能作廢;session把資料存放在了伺服器,安全性也有一定的提高;不過session也不是完全沒有缺點,如果併發使用者很多的時候,會在伺服器生成大量的session,佔用伺服器的資源同時也影響伺服器的效能。而且當用戶退出瀏覽器的時候,購物車session就會清空,而cookie則不會清空。