
本文详解如何在 woocommerce 中为多个商品分类(支持数组形式)统一设置购物车重量上限,通过扩展原单分类限制逻辑,实现跨分类累加计算、精准校验与友好提示。
本文详解如何在 woocommerce 中为多个商品分类(支持数组形式)统一设置购物车重量上限,通过扩展原单分类限制逻辑,实现跨分类累加计算、精准校验与友好提示。
在 WooCommerce 开发中,常需对特定商品类别的总重量施加限制(例如:易碎品 ≤ 5kg、冷链商品 ≤ 10kg)。但原生插件或常见代码片段通常仅支持单个分类的独立限制。当业务需要将多个分类(如 'frozen'、'perishable'、'glassware')合并视为同一重量池进行统一管控时,就必须重构逻辑——既要识别分类组,又要聚合其商品重量并统一校验。
以下是一个生产就绪的完整解决方案,基于 Stack Overflow 经典单分类限制代码升级而来,支持混合配置:既可为单个分类设限,也可为分类数组设统一上限。
✅ 核心实现逻辑
我们通过扩展 $weight_limits 配置数组,允许 category 键值为字符串(单分类)或数组(多分类组合),并在遍历购物车商品时动态判断类型,分别处理:
- 若 category 是数组 → 检查商品是否属于其中任一分类,若是则将该商品重量计入该组的 total;
- 若 category 是字符串 → 按原逻辑匹配单分类并累加;
- 所有分组/单分类的 total 均在结账前统一校验。
? 完整代码示例(添加至主题 functions.php 或专属插件)
// 定义重量限制规则:支持单分类(string)和多分类组合(array)
$weight_limits = array(
// 示例1:单分类限制 —— 'books' 类别总重 ≤ 3kg
array(
'category' => 'books',
'limit' => 3.0,
'message' => '书籍类商品总重量不得超过 3 千克。'
),
// 示例2:多分类组合限制 —— 冷冻+生鲜+玻璃器皿共用同一重量池 ≤ 8kg
array(
'category' => array('frozen', 'perishable', 'glassware'),
'limit' => 8.0,
'message' => '冷冻、生鲜及玻璃制品合计重量不得超过 8 千克。'
),
);
// 计算各限制组的实际总重
add_action('woocommerce_check_cart_items', 'wc_cart_weight_restriction_by_category_group');
function wc_cart_weight_restriction_by_category_group() {
global $woocommerce, $weight_limits;
// 初始化各组累计重量
$totals = array_fill_keys(array_keys($weight_limits), 0.0);
// 遍历购物车商品
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$product = $cart_item['data'];
$product_weight = $product->get_weight() ?: 0;
$product_quantity = $cart_item['quantity'];
if ($product_weight $setting) {
$weight = $product_quantity * $product_weight;
if (is_array($setting['category'])) {
// 多分类组合:任一匹配即计入该组
foreach ($setting['category'] as $cat_slug) {
if (has_term($cat_slug, 'product_cat', $product_id)) {
$totals[$key] += $weight;
break; // 匹配成功即跳出内层循环
}
}
} elseif (has_term($setting['category'], 'product_cat', $product_id)) {
// 单分类匹配
$totals[$key] += $weight;
}
}
}
// 校验每组是否超限
foreach ($weight_limits as $key => $setting) {
if ($totals[$key] > $setting['limit']) {
wc_add_notice(sprintf(
'<strong>限制提醒:</strong> %s 当前总重 %.2f kg,超出上限 %.2f kg。',
esc_html($setting['message']),
$totals[$key],
$totals[$key] - $setting['limit']
), 'error');
}
}
}
⚠️ 关键注意事项
- 权重单位一致性:确保所有商品在后台「产品数据 → 常规」中已正确填写 Weight(单位为 kg),空值或非数字将被忽略;
- 分类层级兼容性:has_term() 自动支持子分类匹配(若需严格限定父级,请改用 wp_get_post_terms() + term_taxonomy_id 判断);
- 性能优化建议:若分类组数量庞大(>10 组),可提前构建分类→规则映射表,避免每次循环重复遍历;
- 错误提示增强:可结合 wc_print_notices() 或 AJAX 实时校验提升用户体验;
- 排除虚拟商品:如需跳过虚拟/下载类商品,可在循环开头添加 if ($product->is_virtual()) continue;。
✅ 总结
本方案通过灵活的数据结构(category 支持 string/array)与双重条件分支(is_array() + has_term()),无缝扩展了 WooCommerce 购物车重量限制能力。它不依赖第三方插件,轻量可靠,且易于维护——新增分类组合只需修改 $weight_limits 数组,无需改动核心逻辑。适用于电商合规管控、物流成本预估、特殊仓储调度等真实业务场景。










