PHP商品SKU设置全攻略:从基础到实战实现
在电商系统中,商品SKU(Stock Keeping Unit,库存量单位)是管理商品规格、库存和价格的核心,一个设计合理的SKU体系不仅能提升用户购物体验,还能简化后台库存管理流程,本文将结合PHP开发实践,详细讲解商品SKU的设置逻辑、数据库设计、代码实现及常见问题解决,助你快速电商SKU系统的开发技巧。
什么是商品SKU?
SKU是商品库存管理的最小可用单元,用于区分不同规格组合的商品,一款T恤有“颜色:红/蓝/黑”和“尺码:S/M/L”两种规格,那么它会产生3×2=6个SKU,分别对应“红色-S码”“红色-M码”……“黑色-L码”等具体商品,每个SKU可独立设置价格、库存、编码等信息。
SKU系统的核心要素
设计SKU系统前,需明确以下核心要素:
商品规格(属性)
商品的分类属性,如颜色、尺码、内存、材质等,每个规格有多个“规格值”(如颜色=红色、蓝色;尺码=S、M)。
SKU组合
多个规格值交叉组合形成的具体商品单元,组合需满足“全排列”(即所有规格值都要参与组合)。
SKU信息
每个组合对应的独立数据,包括:
- SKU编码(如“SKU-001-Red-S”)
- 价格(售价、市场价等)
- 库存(实时库存、库存预警值)
- 商品图片(规格对应的展示图)
- 其他属性(重量、条形码等)
数据库设计:SKU系统的数据基石
合理的数据库设计是SKU系统稳定运行的前提,以下是核心表结构设计(以MySQL为例):
商品基础表(goods)
CREATE TABLE `goods` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品ID', `name` varchar(255) NOT NULL COMMENT '商品名称', `description` text COMMENT '商品描述', `base_price` decimal(10,2) NOT NULL COMMENT '基础价格(默认规格价格)', `status` tinyint(1) DEFAULT '1' COMMENT '商品状态:1上架,0下架', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
规则表(attribute)
存储商品规格分类,如“颜色”“尺码”等。
CREATE TABLE `attribute` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '规格ID', `name` varchar(50) NOT NULL COMMENT '规格名称(如颜色、尺码)', `goods_id` int(11) NOT NULL COMMENT '关联商品ID', `sort` int(11) DEFAULT '0' COMMENT '排序', PRIMARY KEY (`id`), KEY `idx_goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
规格值表(attribute_value)
存储每个规格的具体值,如“红色”“S码”等。
CREATE TABLE `attribute_value` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '规格值ID', `attribute_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_attribute_id` (`attribute_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SKU表(sku)
存储具体的SKU组合信息。
CREATE TABLE `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编码', `price` decimal(10,2) NOT NULL COMMENT 'SKU价格', `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存数量', `image` varchar(255) DEFAULT '' COMMENT 'SKU图片', `spec_values` json NOT NULL COMMENT '规格值组合(如["红色","S"])', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_goods_id_sku_code` (`goods_id`, `sku_code`), KEY `idx_goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
PHP实现:SKU组合与管理的核心逻辑
规格数据结构化
首先需要将前端提交的规格数据整理为“规格-规格值”的层级结构,前端提交:
{ "specs": [ {"name": "颜色", "values": ["红色", "蓝色", "黑色"]}, {"name": "尺码", "values": ["S", "M", "L"]} ] }
PHP处理后可存储为attribute
和attribute_value
表的数据,后续生成SKU组合时需读取此结构。
生成SKU全排列组合
核心逻辑是通过“笛卡尔积”算法生成所有规格值的组合,颜色[红、蓝、黑]和尺码[S、M、L]的组合为:红-S、红-M、红-L、蓝-S、蓝-M、蓝-L、黑-S、黑-M、黑-L。
实现代码(递归法生成笛卡尔积):
/** * 生成规格值的笛卡尔积组合 * @param array $specs 规格数组,格式:[['颜色' => ['红', '蓝']], ['尺码' => ['S', 'M']]] * @return array 组合结果,格式:[['颜色' => '红', '尺码' => 'S'], ['颜色' => '红', '尺码' => 'M']] */ function generateSkuCombinations(array $specs): array { $combinations = [[]]; foreach ($specs as $spec) { $specName = key($spec); $values = current($spec); $temp = []; foreach ($combinations as $combination) { foreach ($values as $value) { $temp[] = array_merge($combination, [$specName => $value]); } } $combinations = $temp; } return $combinations; } // 示例:规格数据 $specs = [ ['颜色' => ['红色', '蓝色', '黑色']], ['尺码' => ['S', 'M', 'L']] ]; $combinations = generateSkuCombinations($specs); print_r($combinations);
输出结果:
Array ( [0] => Array ( [颜色] => 红色 [尺码] => S ) [1] => Array ( [颜色] => 红色 [尺码] => M ) // ... 共9种组合 )
保存SKU数据到数据库
生成组合后,需将每个组合对应的SKU信息(价格、库存、图片等)存入sku
表,代码示例如下:
/** * 保存SKU数据 * @param int $goodsId 商品ID * @param array $skuList SKU列表,格式:[['spec_values' => ['颜色' => '红', '尺码' => 'S'], 'price' => 99.00, 'stock' => 100, 'image' => '...']] * @return bool */ function saveSkus(int $goodsId, array $skuList): bool { $pdo = new PDO('mysql:host=localhost;dbname=shop', 'root', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); try { $pdo->beginTransaction(); // 先删除旧SKU数据(可选,根据业务需求) $deleteSql = "DELETE FROM sku WHERE goods_id = :goods_id"; $deleteStmt = $pdo->prepare($deleteSql); $deleteStmt->execute([':goods_id' => $goodsId]); // 批量插入新SKU数据 $insertSql = "INSERT INTO sku (goods_id, sku_code, price, stock, image, spec_values) VALUES (:goods_id, :sku_code, :price, :stock, :image, :spec_values)"; $insertStmt = $pdo->prepare($insertSql); foreach ($skuList as $sku) { // 生成SKU编码(规则:商品ID-规格值哈希) $specValuesJson = json_encode($sku['spec_values'], JSON_SORT_KEYS); $skuCode = 'SKU-' . $goodsId . '-' . md5($specValuesJson); $insertStmt->execute([ ':goods_id' => $goodsId, ':sku_code' => $skuCode, ':price' => $sku['price'], ':stock'
还没有评论,来说两句吧...