PHP商品多规格功能实现详解:从数据库设计到前端交互
在电商系统中,商品多规格功能是核心需求之一,它允许同一商品存在不同属性组合(如颜色、尺寸、容量等),每种组合对应独立的SKU(Stock Keeping Unit,库存量单位)、价格和库存,本文将从数据库设计、后端逻辑实现到前端交互,详细拆解PHP商品多规格功能的完整实现方案。
多规格功能的核心逻辑与数据库设计
多规格功能的核心是“属性组合生成SKU”:商品有多个规格属性(如颜色:红、蓝;尺寸:S、M),这些属性两两组合形成独立SKU(红色S码、红色M码、蓝色S码、蓝色M码),每个SKU对应自己的价格、库存、编码等信息,实现这一功能,需先设计合理的数据库结构。
核心数据表设计
(1)商品基础表(goods
)
存储商品的基本信息,与规格解耦:
CREATE TABLE `goods` ( `id` int(11) NOT NULL AUTO_INCREMENT, varchar(255) NOT NULL COMMENT '商品标题', `description` text COMMENT '商品描述', `main_img` varchar(255) NOT NULL COMMENT '主图', `is_multi_spec` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否多规格(0:单规格,1:多规格)', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(2)规格属性表(spec_attr
)
存储商品的规格属性(如“颜色”“尺寸”等):
CREATE TABLE `spec_attr` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goods_id` int(11) NOT NULL COMMENT '商品ID', `attr_name` varchar(50) NOT NULL COMMENT '属性名称(如“颜色”)', `attr_sort` int(11) NOT NULL DEFAULT 0 COMMENT '属性排序', PRIMARY KEY (`id`), KEY `idx_goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(3)属性值表(spec_value
)
存储每个规格属性的具体值(如颜色的“红、蓝”,尺寸的“S、M”):
CREATE TABLE `spec_value` ( `id` int(11) NOT NULL AUTO_INCREMENT, `attr_id` int(11) NOT NULL COMMENT '规格属性ID', `value_name` varchar(50) NOT NULL COMMENT '属性值名称(如“红色”)', `value_sort` int(11) NOT NULL DEFAULT 0 COMMENT '属性值排序', PRIMARY KEY (`id`), KEY `idx_attr_id` (`attr_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
(4)SKU表(goods_sku
)
存储属性组合对应的SKU信息:
CREATE TABLE `goods_sku` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goods_id` int(11) NOT NULL COMMENT '商品ID', `sku_code` varchar(64) NOT NULL COMMENT 'SKU编码(如“RED-S”)', `price` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'SKU价格', `stock` int(11) NOT NULL DEFAULT 0 COMMENT 'SKU库存', `sales` int(11) NOT NULL DEFAULT 0 COMMENT 'SKU销量', `spec_values` varchar(255) NOT NULL COMMENT '规格值组合(JSON格式,如{"color":"红色","size":"S"})', PRIMARY KEY (`id`), UNIQUE KEY `uk_goods_sku_code` (`goods_id`, `sku_code`), KEY `idx_goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
表关系说明
goods
与spec_attr
:一对多(一个商品有多个规格属性);spec_attr
与spec_value
:一对多(一个属性有多个值);goods
与goods_sku
:一对多(一个商品有多个SKU,每个SKU对应一个属性组合)。
后端实现:PHP处理多规格逻辑
后端需实现三个核心功能:规格数据管理(增删改查)、SKU组合生成、SKU数据管理,以下以Laravel框架为例(原生PHP逻辑类似,仅调整语法)。
规格数据管理:添加/编辑规格属性与值
(1)添加规格属性
前端传入商品ID和属性名称(如“颜色”),后端存入spec_attr
表:
// 控制器方法:添加规格属性 public function addSpecAttr(Request $request) { $request->validate([ 'goods_id' => 'required|exists:goods,id', 'attr_name' => 'required|string|max:50', ]); SpecAttr::create([ 'goods_id' => $request->goods_id, 'attr_name' => $request->attr_name, 'attr_sort' => $request->input('attr_sort', 0), ]); return response()->json(['code' => 0, 'msg' => '添加成功']); }
(2)添加属性值
前端传入属性ID和属性值名称(如“红色”),后端存入spec_value
表:
// 控制器方法:添加属性值 public function addSpecValue(Request $request) { $request->validate([ 'attr_id' => 'required|exists:spec_attr,id', 'value_name' => 'required|string|max:50', ]); SpecValue::create([ 'attr_id' => $request->attr_id, 'value_name' => $request->value_name, 'value_sort' => $request->input('value_sort', 0), ]); return response()->json(['code' => 0, 'msg' => '添加成功']); }
核心逻辑:SKU组合生成与存储
(1)生成SKU组合
假设商品有2个规格属性:颜色(红、蓝)、尺寸(S、M),则SKU组合为:
[{"color":"红色","size":"S"}, {"color":"红色","size":"M"}, {"color":"蓝色","size":"S"}, {"color":"蓝色","size":"M"}]
生成逻辑:笛卡尔积算法,实现代码如下:
/** * 生成SKU组合(笛卡尔积) * @param array $specValues 规格值数组,格式:[['attr_id'=>1, 'values'=>['红','蓝']], ['attr_id'=>2, 'values'=>['S','M']]] * @return array 组合后的数组,每个元素是一个规格值组合 */ function generateSkuCombinations(array $specValues): array { $combinations = [[]]; foreach ($specValues as $spec) { $temp = []; foreach ($combinations as $combination) { foreach ($spec['values'] as $value) { $temp[] = array_merge($combination, [$spec['attr_name'] => $value]); } } $combinations = $temp; } return $combinations; } // 示例:调用生成组合 $specValues = [ ['attr_name' => '颜色', 'values' => ['红色', '蓝色']], ['attr_name' => '尺寸', 'values' => ['S', 'M']], ]; $combinations = generateSkuCombinations($specValues); // 输出:[["颜色"=>"红色","尺寸"=>"S"], ["颜色"=>"红色","尺寸"=>"M"], ["颜色"=>"蓝色","尺寸"=>"S"], ["颜色"=>"蓝色","尺寸"=>"M"]]
(2)存储SKU数据
前端传入每个组合的价格、库存、SKU编码等信息,后端批量存入goods_sku
表:
// 控制器方法:保存SKU数据 public function saveSkus(Request $request) { $request->validate([ 'goods_id' => 'required|exists:goods,id', 'skus' => 'required|array', 'skus.*.sku_code' => 'required|string', 'skus.*.price' => 'required|numeric|min:0', 'skus.*.stock' => 'required|integer|min:0', ]); $goodsId = $request->goods_id; $skus = $request->skus; // 开启事务 DB::beginTransaction(); try { // 删除旧SKU(编辑时) GoodsSku::where('goods_id', $goodsId)->delete(); // 批量插入新SKU foreach ($skus as $sku) { GoodsSku::create([ 'goods_id' => $goodsId, 'sku_code' => $sku['sku_code'], 'price' => $sku['price'], 'stock' => $sku['stock'], 'sales' => 0, 'spec_values'
还没有评论,来说两句吧...