如何用PHP制作一个功能完善的购物车页面
购物车是电商网站的核心功能之一,它允许用户临时存储选中的商品、调整数量、计算总价,并最终完成下单,本文将详细介绍如何使用PHP(结合HTML、CSS和MySQL)从零开始构建一个功能完善的购物车页面,包括商品展示、添加/删除商品、修改数量、实时计算总价以及购物车数据持久化等关键功能。
准备工作:环境与数据库设计
在开始编码前,需要确保本地开发环境已搭建完成(推荐使用XAMPP或WAMP集成环境,包含PHP、MySQL和Apache),我们需要设计一个简单的数据库来存储商品信息,以及用户购物车数据。
数据库表设计
(1)商品表(products)
用于存储商城中的所有商品信息:
CREATE TABLE `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL COMMENT '商品名称', `price` decimal(10,2) NOT NULL COMMENT '商品价格', `image` varchar(255) DEFAULT NULL COMMENT '商品图片路径', `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存数量', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '商品状态(1:上架,0:下架)', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(2)购物车表(cart)
用于存储用户的购物车数据(假设已登录用户,若未登录可使用Session存储):
CREATE TABLE `cart` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '用户ID', `product_id` int(11) NOT NULL COMMENT '商品ID', `quantity` int(11) NOT NULL DEFAULT '1' COMMENT '购买数量', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `user_product` (`user_id`,`product_id`), FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
初始化测试数据
向products表中插入几条测试商品数据:
INSERT INTO `products` (`id`, `name`, `price`, `image`, `stock`, `status`) VALUES (1, 'iPhone 15 Pro', 7999.00, 'images/iphone15.jpg', 100, 1), (2, 'MacBook Air M2', 8999.00, 'images/macbook.jpg', 50, 1), (3, 'AirPods Pro 2', 1899.00, 'images/airpods.jpg', 200, 1);
项目结构与文件规划
为了代码清晰,建议按以下目录结构组织项目文件:
/shopping-cart
├── config.php # 数据库连接配置
├── functions.php # 公共函数(如添加商品、更新数量等)
├── index.php # 商品列表页面
├── cart.php # 购物车页面
├── add_to_cart.php # 处理添加商品的逻辑(无页面输出)
├── update_cart.php # 处理更新购物车数量的逻辑
├── remove_from_cart.php # 处理删除商品的逻辑
├── assets/
│ ├── css/
│ │ └── style.css # 页面样式
│ └── images/
│ └── products/ # 存放商品图片
└── templates/ # 模板文件(可选,用于分离HTML和PHP)
核心功能实现
数据库连接(config.php)
首先创建数据库连接文件,后续所有PHP页面都需要引入该文件:
<?php
// config.php
$host = 'localhost';
$dbname = 'shopping_cart';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("数据库连接失败: " . $e->getMessage());
}
公共函数(functions.php)
将购物车的核心操作封装为函数,方便复用:
<?php
// functions.php
require_once 'config.php';
/**
* 获取用户购物车中的所有商品
* @param int $userId 用户ID
* @return array 购物车商品列表(包含商品详情)
*/
function getCartItems($userId) {
global $pdo;
$sql = "SELECT c.*, p.name, p.price, p.image
FROM cart c
JOIN products p ON c.product_id = p.id
WHERE c.user_id = :user_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':user_id', $userId, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 添加商品到购物车
* @param int $userId 用户ID
* @param int $productId 商品ID
* @param int $quantity 数量
* @return bool 是否添加成功
*/
function addToCart($userId, $productId, $quantity = 1) {
global $pdo;
try {
// 检查商品是否已在购物车中
$sql = "SELECT * FROM cart WHERE user_id = :user_id AND product_id = :product_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':user_id', $userId, PDO::PARAM_INT);
$stmt->bindParam(':product_id', $productId, PDO::PARAM_INT);
$stmt->execute();
$existingItem = $stmt->fetch(PDO::FETCH_ASSOC);
if ($existingItem) {
// 已存在则更新数量
$newQuantity = $existingItem['quantity'] + $quantity;
$sql = "UPDATE cart SET quantity = :quantity WHERE user_id = :user_id AND product_id = :product_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':quantity', $newQuantity, PDO::PARAM_INT);
$stmt->bindParam(':user_id', $userId, PDO::PARAM_INT);
$stmt->bindParam(':product_id', $productId, PDO::PARAM_INT);
return $stmt->execute();
} else {
// 不存在则插入新记录
$sql = "INSERT INTO cart (user_id, product_id, quantity) VALUES (:user_id, :product_id, :quantity)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':user_id', $userId, PDO::PARAM_INT);
$stmt->bindParam(':product_id', $productId, PDO::PARAM_INT);
$stmt->bindParam(':quantity', $quantity, PDO::PARAM_INT);
return $stmt->execute();
}
} catch (PDOException $e) {
return false;
}
}
/**
* 更新购物车商品数量
* @param int $cartId 购物车记录ID
* @param int $quantity 新数量
* @return bool 是否更新成功
*/
function updateCartItemQuantity($cartId, $quantity) {
global $pdo;
$sql = "UPDATE cart SET quantity = :quantity WHERE id = :cart_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':quantity', $quantity, PDO::PARAM_INT);
$stmt->bindParam(':cart_id', $cartId, PDO::PARAM_INT);
return $stmt->execute();
}
/**
* 从购物车中删除商品
* @param int $cartId 购物车记录ID
* @return bool 是否删除成功
*/
function removeFromCart($cartId) {
global $pdo;
$sql = "DELETE FROM cart WHERE id = :cart_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':cart_id', $cartId, PDO::PARAM_INT);
return $stmt->execute();
}
/**
* 计算购物车总价
* @param array $cartItems 购物车商品列表
* @return float 总价
*/
function calculateCartTotal($cartItems) {
$total = 0;
foreach ($cartItems as $item) {
$total += $item['price'] * $item['quantity'];
}
return $total;
}
商品列表页面(index.php)
展示所有商品,并提供“加入购物车”按钮:
<?php require_once 'config.php'; require_once 'functions.php'; // 获取所有商品 $sql = "SELECT * FROM products WHERE status = 1"; $stmt = $pdo->query($sql); $products = $stmt->fetchAll(PDO::FETCH_ASSOC); ?> <!DOCTYPE html> <html lang="zh-CN"> <head>



还没有评论,来说两句吧...