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

修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:58:42