2012年1月17日

[php] jQuery ajax 購物車實作

這次的練習是使用php實作購物車,購物紀錄使用session,資料庫使用mysql,php連線使用PDO
下面的程式碼只是提出某些主要的function,其他使用文字做說明

1. 資料庫連線include檔


//資料庫連線資料
define('user','root');
define('password','XXX');
define('dbname','test');

2. 資料庫連線class(繼承用)

class Mysql {

    private $dbname = dbname;
    //使用prepare執行查詢,並回傳結果
    public function executePrepareSelect($sql, $param) {
        $db = new PDO("mysql:host=localhost;dbname=$this->dbname", user, password);
        try {
            $stmt = $db->prepare($sql);
            if (count($param) > 0) {
                foreach ($param as $key => $val) {
                    $this->bindParameters($stmt, $key, $val);
                }
            }
            $stmt->execute();
            $db = null;
        } catch (PDOException $e) {
            $e->getMessage();
            return false;
        }
        return $stmt->fetchAll();
    }
    //用來bind參數
    private function bindParameters($stmt, $key, $value) {
        if (is_int($value)) {
            $stmt->bindParam(':' . $key, $value, PDO::PARAM_INT);
        } else if (is_bool($value)) {
            $stmt->bindParam(':' . $key, $value, PDO::PARAM_BOOL);
        } else if (is_string($value)) {
            $stmt->bindParam(':' . $key, $value, PDO::PARAM_STR);
        } else {
            $stmt->bindParam(':' . $key, $value);
        }
    }
}

Mysql類別主要用來隔離出資料庫select、insert等等所需要的方法,加速其他功能的開發

3. 商品class

class Product extends Mysql {

     //使用商品編號查詢商品
    function getProductById($pid) {
        $param = array("id" => $pid);
        $sql = $this->createPrepareSelectStatement($param);
        $result = $this->executePrepareSelect($sql, $param);
        if ($result)
            return $result[0];
        else
            return "error";
    }
    //新增商品
    function insertProduct($name, $price, $caption) {
        $param = array("ProductName"=>$name,"Price"=>$price,"Caption"=>$caption);
        $sql = $this->createPrepareInsertStatement($param);
        if($this->executePrepareInsert($sql, $param)){
            return true;
        }else{
            return false;
        }
    }
}

雖然商品類別應該代表一個商品,為了簡便就不把商品單獨做出一個類別,商品類別目的在於提供商品的查詢、新增等方法,直接繼承Mysql類別加速開發,createXXXStatement方法只是給予需求的參數就可以產出sql新增或查詢語法

4. 購物車類別

class ShopCar {
    private $items = array(); //購買的商品
    private $count; //新增商品的旗標
    private $total; //總價
    //加入商品
    public function addItem($pid, $num) {
        try {
            for ($i = 0; $i < $num; $i++) {
                $this->items[$this->count] = $pid;
                $this->count++;
            }
            $this->total = $this->setTotal();
            return true;
        } catch (Exception $e) {
            echo $e->getMessage();
            return false;
        }
    }
    //刪除物品
    public function deleteItem($pid){
        for($i=0;$iitems);$i++){
            if($this->items[$i] == $pid){
                unset($this->items[$i]);
            }
        }
    }
    //產出購買物品列表
    public function getAllItems(){
        $tmp = array();
        foreach($this->items as $item){
            if(empty($tmp[$item])){
                $tmp[$item] = 1;
            }else{
                $tmp[$item]++;
            }
        }
        $pending = "";
        $pending .= "";
        foreach($tmp as $key=>$value){
            $p = new Product();
            $item = $p->getProductById($key);
            $name = $item["ProductName"];
            $price = $item["Price"];
            $sumPrice = intval($value) * intval($item["Price"]);
            $caption = $item["Caption"];
            $pending .= "";
        }
        $pending .= '
編號名稱數量單價總價說明
$key$name$value$price$sumPrice$caption
'; return $pending; } }

代表一輛購物車的類別,使用一個陣列(items)記錄使用者購買的商品ID,需要各種資訊如目前購買總價、商品列表都從陣列中提出ID再做查詢,減少新增或刪除商品時的資料庫讀取次數

5. ajax處理商品頁面

if (!isset($_SESSION['car'])) {
    die("error");
}
$car = $_SESSION['car'];
if (strval($_GET['type']) == "add") {
    //加入商品
    if (empty($_GET['pid'])) {
        print "pid not set";
        exit();
    }
    $success = array();
    if ($car->addItem(intval($_GET['pid']), intval($_GET['num']))) {
        $success[0] = "product " . $_GET['pname'] . " add success";
        $success[1] = strval($car->getTotal());
        print json_encode($success);
    } else {
        $success[0] = "error";
        print json_encode($success);
    }
} else if (strval($_GET['type']) == "reset") {
    //重製購物車
    $success = array();
    if ($car->resetCar()) {
        $success[0] = "reset success";
        $success[1] = strval($car->getTotal());
        print json_encode($success);
    } else {
        $success[0] = "reset fail";
        print json_encode($success);
    }
}

負責處理ajax傳來的指令,使用type區分要求的動作,add是加入商品、reset是重製購物車,結果回傳部分使用json

6. javascript傳送function

function ajaxProduct(targetUrl,GETdata,resultArea,money){
    //targetUrl  -> ajax傳送的頁面
    //GETdata    -> 傳送ajax的參數,使用GET方式傳送
    //resultArea -> 顯示結果狀態的區塊
    //money      -> 顯示目前的總價的區塊
    $.ajax({
        url:targetUrl,
        data:GETdata,
        dataType:"json",
        error:function(xhr,status,thrown){
            $(resultArea).html(status);
        },
        success:function(result,status,xhr){
            $(resultArea).html(result[0]);
            $(money).html(result[1]);
        }
    });
}

最後一個就是負責傳送與接收ajax指令的function,這裡使用到jQuery的ajax功能,比較方便跟快速


以上就是這次的購物車實作內容,如果有不對的地方還請多多指教阿!謝謝!