You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

optgroup标签重复问题:同类别产品无法归入同一optgroup分组

问题解决:避免重复创建optgroup分组

当前代码能实现按类别分组,但每个产品都会生成独立的optgroup,导致同一类别被重复创建。正确的逻辑应该是同一类别下的所有产品归到同一个optgroup中。

问题根源

原代码在遍历每个产品时,都会生成一对<optgroup>标签,所以同一类别的每个产品都会触发一次分组创建,造成重复。

优化方案

  1. 先按类别聚合数据:通过SQL JOIN一次性获取产品及其所属类别,避免循环内重复查询数据库,提升效率。
  2. 按类别分组存储:将查询结果整理为以类别为键的数组,方便后续遍历输出。
  3. 遍历分组输出:先输出类别对应的optgroup,再在组内循环输出该类别下的所有产品选项。

修正后的代码

<select style="width: 25%;" name="item[]" id="item1" class="item browser-default custom-select-new"> 
    <option value="" disabled selected>点击查看产品</option>
<?php
$conn_register = mysqli_connect('localhost', 'root', '', 'register');
$Comid = "27";

// 使用JOIN一次性获取产品及对应类别,同时按类别排序
$records = mysqli_query($conn_register, "
    SELECT cp.*, ap.category 
    FROM customer_product cp
    JOIN addproducts ap ON cp.product = ap.name
    WHERE cp.customer = '$Comid'
    ORDER BY ap.category
");

// 按类别分组存储产品
$productsByCategory = [];
while ($data = mysqli_fetch_array($records)) {
    $category = $data['category'];
    if (!isset($productsByCategory[$category])) {
        $productsByCategory[$category] = [];
    }
    $productsByCategory[$category][] = $data;
}

// 遍历每个类别,输出optgroup和对应的选项
foreach ($productsByCategory as $category => $products) {
    echo '<optgroup label="' . htmlspecialchars($category) . '">';
    foreach ($products as $product) {
        echo '<option value="' . htmlspecialchars($product['product']) . '"  
                data-new_price_rate="' . htmlspecialchars($product['new_total_rate']) . '" 
                data-description="' . htmlspecialchars($product['description']) . '" 
                data-tax="' . htmlspecialchars($product['tax']) . '"
                data-PriceRate_NoDiscount="' . htmlspecialchars($product['new_price_rate']) . '">'
            . htmlspecialchars($product['product']) . '</option>';
    }
    echo '</optgroup>';
}
?>
</select>

额外优化点

  • 使用htmlspecialchars()转义输出内容,避免XSS安全问题。
  • 用JOIN替代循环内的多次查询,减少数据库交互次数,提升性能。
  • 建议使用预处理语句(Prepared Statements)处理SQL查询,防止SQL注入风险,示例如下:
// 预处理语句示例
$stmt = $conn_register->prepare("
    SELECT cp.*, ap.category 
    FROM customer_product cp
    JOIN addproducts ap ON cp.product = ap.name
    WHERE cp.customer = ?
    ORDER BY ap.category
");
$stmt->bind_param("s", $Comid);
$stmt->execute();
$records = $stmt->get_result();
// 后续处理逻辑同上

内容的提问来源于stack exchange,提问作者Pierre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:00:35