PHP表单中产品价格与选择项关联及数据库存储教程
在电商类网站开发中,经常会遇到这样的需求:用户在下单时需要选择不同的产品规格,比如购买手机时选择存储容量,不同容量对应不同的价格,选中某个规格后页面自动显示对应价格,同时提交订单后要把选择的规格和对应价格存入数据库。本文结合实际案例,完整讲解如何在PHP表单中实现产品价格与选择项的关联,以及如何完成数据库存储操作。
一、前期准备
首先我们需要创建一个简单的产品选择表单,同时准备对应的数据库表结构。假设我们的产品是手机,可选规格为存储容量:128G、256G、512G,每个规格对应不同的价格。
1.1 数据库表设计
我们需要两张表,一张存储产品规格和对应价格,另一张存储用户提交的订单信息。表结构如下:
| 表名 | 字段名 | 类型 | 说明 |
|---|---|---|---|
| product_spec | id | int(11) | 主键,自增 |
| spec_name | varchar(50) | 规格名称,如128G | |
| price | decimal(10,2) | 对应价格 | |
| product_id | int(11) | 关联的产品ID | |
| order_record | id | int(11) | 主键,自增 |
| spec_id | int(11) | 选择的规格ID | |
| spec_name | varchar(50) | 选择的规格名称 | |
| order_price | decimal(10,2) | 订单对应价格 | |
| create_time | datetime | 订单创建时间 |
我们可以先往product_spec表中插入测试数据,比如产品ID为1的手机对应的三个规格:
INSERT INTO product_spec (spec_name, price, product_id) VALUES
('128G', 3999.00, 1),
('256G', 4499.00, 1),
('512G', 4999.00, 1);二、前端表单实现
前端表单需要展示所有可选的规格,并且当用户选择不同规格时,通过JavaScript动态更新显示的价格,同时表单提交时要把选中的规格ID传递给后端PHP处理。
首先编写HTML表单部分,注意这里提到的<form>、<select>、<option>等标签都需要按照规则转义,实际代码中表单标签是正常HTML,这里只是说明标签名称需要转义的情况。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>手机购买选择</title>
<script src="https://ipipp.com/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h3>选择手机存储容量</h3>
<form action="submit_order.php" method="post">
<!-- 存储规格选择下拉框 -->
<label for="spec_select">存储容量:</label>
<select id="spec_select" name="spec_id" onchange="updatePrice()">
<option value="">请选择容量</option>
<option value="1" data-price="3999.00">128G</option>
<option value="2" data-price="4499.00">256G</option>
<option value="3" data-price="4999.00">512G</option>
</select>
<br><br>
<!-- 价格显示区域 -->
<p>当前选择价格:<span id="show_price">请先选择容量</span> 元</p>
<br>
<input type="submit" value="提交订单">
</form>
<script>
// 定义更新价格的函数
function updatePrice() {
// 获取选中的option元素
var selectObj = document.getElementById("spec_select");
var selectedOption = selectObj.options[selectObj.selectedIndex];
// 获取data-price属性的值
var price = selectedOption.getAttribute("data-price");
var showPriceObj = document.getElementById("show_price");
if (price) {
showPriceObj.innerHTML = price;
} else {
showPriceObj.innerHTML = "请先选择容量";
}
}
</script>
</body>
</html>上面的代码中,我们在每个<option>标签上添加了data-price自定义属性,存储对应规格的价格,当用户切换选择项时,触发updatePrice函数,从选中项的属性中读取价格并显示在页面上,这样就实现了前端的价格与选择项关联。
三、后端PHP处理与数据库存储
用户提交表单后,后端PHP需要接收选中的规格ID,查询对应的规格信息和价格,然后存入订单表中。这里我们使用PDO方式操作数据库,避免SQL注入风险。
首先创建数据库连接文件db_config.php:
<?php
// 数据库配置
$db_host = '127.0.0.1';
$db_name = 'test_shop';
$db_user = 'root';
$db_pass = '123456';
try {
// 创建PDO连接实例
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8", $db_user, $db_pass);
// 设置PDO错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("数据库连接失败:" . $e->getMessage());
}
?>接下来编写处理订单提交的submit_order.php文件:
<?php
// 引入数据库配置文件
require_once 'db_config.php';
// 检查是否接收到表单提交的spec_id
if (!isset($_POST['spec_id']) || empty($_POST['spec_id'])) {
die("请先选择产品规格");
}
$spec_id = intval($_POST['spec_id']);
// 查询选中的规格信息
$sql = "SELECT spec_name, price FROM product_spec WHERE id = :spec_id LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':spec_id', $spec_id, PDO::PARAM_INT);
$stmt->execute();
$spec_info = $stmt->fetch(PDO::FETCH_ASSOC);
// 如果没查询到对应的规格,提示错误
if (!$spec_info) {
die("未找到对应的产品规格");
}
$spec_name = $spec_info['spec_name'];
$order_price = $spec_info['price'];
$create_time = date('Y-m-d H:i:s');
// 插入订单数据到order_record表
$insert_sql = "INSERT INTO order_record (spec_id, spec_name, order_price, create_time)
VALUES (:spec_id, :spec_name, :order_price, :create_time)";
$insert_stmt = $pdo->prepare($insert_sql);
$insert_stmt->bindParam(':spec_id', $spec_id, PDO::PARAM_INT);
$insert_stmt->bindParam(':spec_name', $spec_name, PDO::PARAM_STR);
$insert_stmt->bindParam(':order_price', $order_price, PDO::PARAM_STR);
$insert_stmt->bindParam(':create_time', $create_time, PDO::PARAM_STR);
if ($insert_stmt->execute()) {
echo "订单提交成功!<br>";
echo "您选择的规格:" . $spec_name . "<br>";
echo "订单价格:" . $order_price . " 元<br>";
echo "订单创建时间:" . $create_time;
} else {
echo "订单提交失败,请重试";
}
?>上面的PHP代码中,我们首先验证接收到的spec_id是否合法,然后通过参数绑定的方式查询对应的规格信息,避免SQL注入。获取到规格名称和价格后,再将完整订单信息插入到order_record表中,最后给用户返回提交结果。
四、注意事项
- 前端的价格更新除了用
data-price属性存储,也可以通过Ajax请求后端接口获取实时价格,避免前端数据被篡改,更安全的方式是以后端查询到的价格为准,前端的动态显示仅作用户体验优化。 - 实际项目中需要对用户输入做更全面的校验,比如
spec_id是否存在、产品是否已下架等。 - 数据库操作建议使用事务,当插入订单失败时可以回滚,保证数据一致性。
- 如果产品规格较多,也可以把规格和价格通过JSON格式传给前端,再通过JavaScript遍历生成选择项,减少前端的硬编码。