PHP商品多规格功能实现全解析:从设计到实战
在电商系统中,商品多规格功能是核心需求之一,无论是服装的“尺码+颜色”、电子产品的“内存+颜色”,还是食品的“规格+口味”,多规格组合直接影响商品库存、价格和用户购买体验,本文将从多规格的底层设计、前端交互、后端逻辑实现到库存管理,详细拆解PHP如何高效实现商品多规格功能。
多规格功能的底层设计:数据结构是关键
多规格功能的核心在于如何用合理的数据库结构存储规格组合及其对应的属性(价格、库存、SKU编码等),常见的设计思路有两种:规格矩阵法和规格属性法,其中规格矩阵法更直观且易于扩展,适合大多数电商场景。
核心表结构设计
(1)商品基础表(goods)
存储商品基本信息,与规格无关:
CREATE TABLE `goods` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品ID', varchar(255) NOT NULL COMMENT '商品标题', `description` text COMMENT '商品描述', `main_image` varchar(255) COMMENT '主图', `status` tinyint(1) DEFAULT 1 COMMENT '状态:1上架,0下架', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(2)规格组表(spec_groups)
定义商品的规格分类(如“尺码”“颜色”),一个商品可包含多个规格组:
CREATE TABLE `spec_groups` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '规格组ID', `goods_id` int(11) NOT NULL COMMENT '商品ID', `name` varchar(50) NOT NULL COMMENT '规格组名称(如“尺码”“颜色”)', `sort` int(11) DEFAULT 0 COMMENT '排序', PRIMARY KEY (`id`), KEY `idx_goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(3)规格值表(spec_values)
存储每个规格组的具体值(如“尺码”包含“S/M/L”,“颜色”包含“红/蓝/绿”):
CREATE TABLE `spec_values` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '规格值ID', `group_id` int(11) NOT NULL COMMENT '所属规格组ID', `value` varchar(50) NOT NULL COMMENT '规格值(如“S”“红色”)', `sort` int(11) DEFAULT 0 COMMENT '排序', PRIMARY KEY (`id`), KEY `idx_group_id` (`group_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(4)SKU表(product_sku)
存储规格组合对应的属性(价格、库存、SKU编码),是多规格的核心数据表:
CREATE TABLE `product_sku` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'SKU ID', `goods_id` int(11) NOT NULL COMMENT '商品ID', `sku_code` varchar(100) NOT NULL COMMENT 'SKU编码(如“SKU2023001”)', `price` decimal(10,2) NOT NULL COMMENT '售价', `cost_price` decimal(10,2) DEFAULT 0 COMMENT '成本价', `stock` int(11) DEFAULT 0 COMMENT '库存', `sales` int(11) DEFAULT 0 COMMENT '销量', `spec_key` varchar(255) NOT NULL COMMENT '规格组合键(如"S:红色,M:蓝色”),用于快速匹配', `spec_value` varchar(255) NOT NULL COMMENT '规格组合值(如"尺码:S,颜色:红色”),用于前端展示', PRIMARY KEY (`id`), KEY `idx_goods_id` (`goods_id`), KEY `idx_spec_key` (`spec_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
数据结构示例
以一件“纯棉T恤”为例,数据如下:
-
规格组表:
spec_groups
| id | goods_id | name | sort | |----|----------|------|------| | 1 | 1 | 尺码 | 1 | | 2 | 1 | 颜色 | 2 | -
规格值表:
spec_values
| id | group_id | value | sort | |----|----------|-------|------| | 1 | 1 | S | 1 | | 2 | 1 | M | 2 | | 3 | 1 | L | 3 | | 4 | 2 | 白色 | 1 | | 5 | 2 | 黑色 | 2 | -
SKU表:
product_sku
| id | goods_id | sku_code | price | stock | spec_key | spec_value | |----|----------|----------|-------|-------|------------------------|--------------------------------| | 1 | 1 | SKU001 | 59.00 | 100 | S:白色,M:黑色 | 尺码:S,颜色:白色 | | 2 | 1 | SKU002 | 59.00 | 150 | M:白色 | 尺码:M,颜色:白色 | | 3 | 1 | SKU003 | 59.00 | 80 | L:黑色 | 尺码:L,颜色:黑色 |
后端实现:规格数据的管理与组合
后端核心功能包括:规格数据增删改、SKU组合生成、库存与价格查询,以下以PHP+MySQL为例,拆解关键逻辑。
规格数据的CRUD操作
(1)添加规格组与规格值
// 添加规格组(如“尺码”)
function addSpecGroup($goodsId, $name) {
$sql = "INSERT INTO spec_groups (goods_id, name) VALUES (?, ?)";
return pdo_execute($sql, [$goodsId, $name]);
}
// 添加规格值(如“S”)
function addSpecValue($groupId, $value) {
$sql = "INSERT INTO spec_values (group_id, value) VALUES (?, ?)";
return pdo_execute($sql, [$groupId, $value]);
}
(2)获取商品的所有规格及SKU
/**
* 获取商品规格及SKU列表
* @param int $goodsId 商品ID
* @return array [
* 'spec_groups' => [['id'=>1, 'name'=>'尺码', 'values'=>['S','M']]],
* 'skus' => [['spec_key'=>'S:白色', 'price'=>59, 'stock'=>100]]
* ]
*/
function getGoodsSpecs($goodsId) {
// 1. 获取规格组
$groups = pdo_query("SELECT * FROM spec_groups WHERE goods_id = ?", [$goodsId]);
// 2. 获取每个规格组的规格值
foreach ($groups as &$group) {
$values = pdo_query("SELECT value FROM spec_values WHERE group_id = ? ORDER BY sort", [$group['id']]);
$group['values'] = array_column($values, 'value');
}
// 3. 获取SKU列表
$skus = pdo_query("SELECT * FROM product_sku WHERE goods_id = ?", [$goodsId]);
return [
'spec_groups' => $groups,
'skus' => $skus
];
}
SKU组合的生成与存储
当用户添加或修改规格时,后端需要生成所有可能的规格组合,并存储对应的SKU信息。“尺码(S/M/L)”和“颜色(白/黑)”会生成3×2=6种组合。
(1)生成规格组合(笛卡尔积)
/**
* 生成规格组合(笛卡尔积)
* @param array $specs 规格数据 [['name'=>'尺码', 'values'=>['S','M']], ['name'=>'颜色', 'values'=>['白','黑']]]
* @return array 组合列表 [['尺码'=>'S','颜色'=>'白'], ['尺码'=>'S','颜色'=>'黑'], ...]
*/
function generateSpecCombinations($specs) {
$combinations = [[]];
foreach ($specs as $spec) {
$temp = [];
foreach ($combinations as $combination) {
foreach ($spec['values'] as $value) {
$temp[] = array_merge($combination, [$spec['name'] => $value]);
}
}
$combinations = $temp;
}
return $combinations;
}
// 示例:$specs = [['name'=>'尺码', 'values'=>['S','M']], ['name'=>'颜色', 'values


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