修改WooCommerce中特定配送类别的购物车商品总重量计算
修复特定配送类别购物车商品重量计算函数
你的需求很清晰:Table Rate Shipping插件只会按购物车总重量算运费,但你需要排除FREE shipping类别的商品,只统计weight based shipping类别的商品总重量(也就是案例里的2.6kg)。咱们先拆解原代码里的几个坑,再给你修复好的函数:
原函数的问题:
$this调用错误:在独立函数里不能直接用$this指代购物车对象,得用WooCommerce提供的全局购物车实例WC()->cart- 变量名笔误:循环里写了
$value['data'],但循环变量是$values,这会直接导致PHP报错 - return位置错误:把
return放在foreach循环内部,第一次循环就直接返回结果了,根本没遍历完所有购物车商品 - 函数复用性差:固定死了要筛选的shipping class,没法灵活适配不同场景
- shipping class判断可以更严谨:直接匹配slug没问题,但如果有多个目标类别,或者怕slug拼写错误,可以同时支持ID匹配
修复后的函数
// 计算指定配送类别的购物车商品总重量 if (!function_exists('get_cart_shipping_class_weight')) { function get_cart_shipping_class_weight($target_shipping_classes) { $total_weight = 0; // 获取WooCommerce购物车实例,避免未初始化的情况 $cart = WC()->cart; if (!$cart) return $total_weight; foreach ($cart->get_cart() as $cart_item_key => $cart_item) { $product = $cart_item['data']; // 跳过本身没有重量的商品 if (!$product->has_weight()) continue; // 获取当前商品的配送类别slug和ID $item_slug = $product->get_shipping_class(); $item_id = $product->get_shipping_class_id(); // 判断当前商品是否属于目标类别:支持单个slug/ID,或多个组成的数组 $is_target = false; if (is_array($target_shipping_classes)) { $is_target = in_array($item_slug, $target_shipping_classes) || in_array($item_id, $target_shipping_classes); } else { $is_target = ($item_slug === $target_shipping_classes) || ($item_id == $target_shipping_classes); } if ($is_target) { // 累加计算:商品单重 × 购买数量 $total_weight += (float)$product->get_weight() * $cart_item['quantity']; } } // 保留过滤钩子,方便后续扩展修改 return apply_filters('woocommerce_cart_shipping_class_weight', $total_weight, $target_shipping_classes); } }
针对你的场景怎么用?
假设你的weight based shipping类别的商品,对应的配送类别slug是weight-based-shipping(你可以在WooCommerce后台「配送」→「配送类别」里查看实际的slug或ID),直接调用函数即可:
// 获取实际应收费的重量 $chargeable_weight = get_cart_shipping_class_weight('weight-based-shipping'); // 输出结果就是2.6kg,和你需要的一致 echo '实际收费重量:' . $chargeable_weight . 'kg';
如果需要同时统计多个配送类别,传数组就行:
$chargeable_weight = get_cart_shipping_class_weight(['weight-based-shipping', 'premium-shipping']);
让Table Rate Shipping用这个重量计算运费
要让插件用这个自定义重量来算运费,只需要添加一个过滤钩子替换默认的购物车总重量:
add_filter('woocommerce_cart_contents_weight', function($original_total_weight) { // 替换成你的目标配送类别 return get_cart_shipping_class_weight('weight-based-shipping'); });
这样插件就会用2.6kg而不是3.0kg来计算运费了。
内容的提问来源于stack exchange,提问作者Tony Tan
相关产品推荐
相关产品推荐

