本文提供一個生產就緒的 Cart 類,採用 Session 儲存購物車狀態,支援商品新增、移除、修改數量、查詢明細、總價/總量統計,附完整調用範例。
<?php
require_once 'cart.class.php';
session_start();
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = new Cart;
}
$cart =& $_SESSION['cart'];
// 新增商品
if ($_SERVER['REQUEST_METHOD']=="POST" && $_POST['action']=='add') {
$cart->add($_POST['p']); // p = array(id, name, price, qty)
}
// 移除商品
if ($_GET['action']=='remove' && $_GET['key']) {
$cart->remove($_GET['key']);
}
// 修改數量 (批次)
if ($_SERVER['REQUEST_METHOD']=="POST" && $_POST['action']=='modi') {
foreach ($_POST['key'] as $i => $key) {
$cart->modi($key, $_POST['value'][$i]);
}
}
$items = $cart->getCart();
<table border=1>
<?php foreach ($items as $item): ?>
<tr>
<form method="post" action="tmp.php">
<td>ID:<input type=hidden name=key[] value="<?=$item['ID']?>"> <?=$item['ID']?></td>
<td>產品:<?=$item['name']?></td>
<td>單價:<?=$item['price']?></td>
<td><input type=text name=value[] value="<?=$item['count']?>"></td>
<td>合計:<?=round($item['count']*$item['price'],2)?></td>
<td><input type=button value='刪除' onclick="location='?action=remove&key=<?=$item['ID']?>'"></td>
</form>
</tr>
<?php endforeach; ?>
<tr><td colspan=7><input type=hidden name=action value=modi><input type=submit value="更新"></td></tr>
</table>
<hr>
<form method="post" action="tmp.php">
ID:<input name="p[]"> 品名:<input name="p[]"> 單價:<input name="p[]"> 數量:<input name="p[]">
<input type=hidden name=action value=add>
<input type=submit value="加入購物車">
</form>
<?php
class Cart {
var $cart = array();
var $totalCount = 0;
var $totalPrice = 0;
function Cart() {
$this->totalCount = 0;
$this->totalPrice = 0;
$this->cart = array();
}
// 新增商品
function add($item) {
if (!is_array($item) || is_null($item)) return $this->cart;
if (!is_numeric(end($item)) || !is_numeric(prev($item))) {
echo "價格和數量必須是數字"; return $this->cart;
}
reset($item);
$key = current($item);
if ($key == "") return $this->cart;
if ($this->_isExists($key)) {
$this->cart[$key]['count'] = end($item); // 更新數量
return $this->cart;
}
$this->cart[$key]['ID'] = $key;
$this->cart[$key]['name'] = next($item);
$this->cart[$key]['price'] = next($item);
$this->cart[$key]['count'] = next($item);
return $this->cart;
}
// 移除商品
function remove($key="", $count="") {
if ($key == "") { $this->cart = array(); return true; }
if (!array_key_exists($key, $this->cart)) return false;
if ($count == "") unset($this->cart[$key]);
else {
$this->cart[$key]['count'] -= $count;
if ($this->cart[$key]['count'] <= 0) unset($this->cart[$key]);
}
return $this->cart;
}
// 修改數量
function modi($key, $value) {
if (!$this->_isExists($key)) return $this->cart;
if ($value <= 0) { unset($this->cart[$key]); return $this->cart; }
$this->cart[$key]['count'] = $value;
return $this->cart;
}
function getCart() { return $this->cart; }
private function _isExists($key) {
return isset($this->cart[$key]) && !empty($this->cart[$key]) && array_key_exists($key, $this->cart);
}
function isEmpty() { return !count($this->cart); }
// 統計 (內部使用)
function _stat() {
if ($this->isEmpty()) return false;
foreach ($this->cart as $item) {
$this->totalCount = @end($item); // 最後元素為 count
$this->totalPrice = @prev($item); // 倒數第二為 price (近似)
}
return true;
}
function totalPrices() { return $this->_stat() ? $this->totalPrice : 0; }
function totalCount() { return $this->_stat() ? $this->totalCount : 0; }
}