如何基于MySQL数据用PHP生成产品所有选项组合的SKU?
生成产品选项组合及对应SKU的PHP实现方案
我以前能轻松处理这类技术问题,但离开开发领域7年多了,现在思路有点生疏。需求是输出客户可选的所有产品选项组合,以及由产品SKU追加各选项SKU构成的最终SKU。所用系统老旧,MySQL数据存储结构不够合理,以下是数据示例和期望的PHP实现效果(以单个多选项产品为例):
数据库表结构
products表
| products.id | products.sku |
|---|---|
| 1 | a |
options表
| options.id | options.product_id |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
option_values表
| option_values.id | option_values.option_id | option_values.value |
|---|---|---|
| 1 | 1 | b |
| 2 | 1 | c |
| 3 | 1 | d |
| 4 | 2 | e |
| 5 | 2 | f |
| 6 | 3 | g |
| 7 | 3 | h |
| 8 | 4 | i |
| 9 | 4 | j |
| 10 | 4 | k |
期望输出
需要遍历所有选项组合并输出对应的SKU,示例如下:
| Possible SKUs(可能的SKU) |
|---|
| abegi |
| acegi |
| adegi |
| abfgi |
| acfgi |
| adfgi |
| abehi |
| acehi |
| adehi |
| abegj |
| acegj |
| adegj |
| abegk |
| acegk |
| adegk |
| [etc] |
当前问题
目前我采用逐个产品、逐个选项、逐个选项值的遍历方式,但显然无法覆盖所有组合场景,怀疑自己有遗漏,恳请提供解决方案。
解决方案
步骤1:从数据库获取结构化数据
先从数据库取出产品SKU,以及按选项分组的选项值列表:
<?php // 假设已通过PDO建立MySQL连接,$pdo为连接实例 $productId = 1; // 获取产品基础SKU $productStmt = $pdo->prepare("SELECT sku FROM products WHERE id = ?"); $productStmt->execute([$productId]); $productSku = $productStmt->fetchColumn(); // 按选项分组获取所有选项值,保证选项顺序固定 $optionsStmt = $pdo->prepare(" SELECT ov.option_id, ov.value FROM options o JOIN option_values ov ON o.id = ov.option_id WHERE o.product_id = ? ORDER BY o.id "); $optionsStmt->execute([$productId]); $optionGroups = []; while ($row = $optionsStmt->fetch(PDO::FETCH_ASSOC)) { $optionGroups[$row['option_id']][] = $row['value']; } // 转为按选项顺序排列的二维数组 $optionGroups = array_values($optionGroups); ?>
步骤2:计算选项的笛卡尔积
核心是实现笛卡尔积算法,生成所有可能的选项组合:
<?php // 计算多数组笛卡尔积的函数 function cartesianProduct($arrays) { $result = [[]]; foreach ($arrays as $array) { $temp = []; foreach ($result as $existingCombination) { foreach ($array as $item) { $temp[] = array_merge($existingCombination, [$item]); } } $result = $temp; } return $result; } // 生成所有选项组合 $allCombinations = cartesianProduct($optionGroups); ?>
步骤3:生成并输出最终SKU
遍历所有组合,拼接产品SKU与选项值得到最终结果:
<?php // 输出结果表格 echo "<table><thead><tr><th>Possible SKUs(可能的SKU)</th></tr></thead><tbody>"; foreach ($allCombinations as $combination) { $finalSku = $productSku . implode('', $combination); echo "<tr><td>$finalSku</td></tr>"; } echo "</tbody></table>"; ?>
关键说明
- 笛卡尔积是解决多选项组合问题的核心,能确保覆盖所有可能的选项搭配
- 按选项ID排序保证了选项值的拼接顺序固定(如先选项1的value,再选项2的,以此类推)
- 代码兼容任意数量的选项和选项值,无需针对固定数量的选项硬编码
内容的提问来源于stack exchange,提问作者olimortimer
相关产品推荐
相关产品推荐

