WooCommerce购物车自定义分类法术语计数及运费按计数倍数计算问题排查
修复WooCommerce按自定义分类术语数量计算运费的问题
我帮你找到了问题的根源,同时给你修正后的代码和排查思路:
问题原因分析
你的代码核心问题出在存储和去重自定义分类术语的方式上:
wp_get_post_terms()返回的是WP_Term对象的数组,你直接把整个对象数组塞进$mojarray里。array_unique()无法正确处理对象数组,因为对象是引用类型,它没法判断两个对象是否代表同一个术语。所以$noviarray实际上和原数组没区别,最后计数器$counter就变成了购物车商品的数量,而不是唯一术语的数量。
修复后的代码
我调整了代码逻辑,改为存储术语的slug(或者ID,选你方便的),这样 array_unique() 就能正确去重了,同时加了错误处理避免没有分类术语的商品报错:
add_filter( 'woocommerce_package_rates', 'calculate_shipping_based_on_unique_city_terms' ); function calculate_shipping_based_on_unique_city_terms( $rates ) { // 确保购物车对象存在 if ( ! WC()->cart ) return $rates; $cart = WC()->cart; // 存储唯一的city术语slug $unique_cities = array(); foreach ( $cart->get_cart() as $cart_item ) { $product_id = $cart_item['product_id']; // 获取商品的city分类术语,只返回slug字段,避免冗余数据 $terms = wp_get_post_terms( $product_id, 'city', array( 'fields' => 'slugs' ) ); // 如果商品有city术语,就合并到数组里 if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) { $unique_cities = array_merge( $unique_cities, $terms ); } } // 去重并统计唯一术语的数量 $unique_city_count = count( array_unique( $unique_cities ) ); // 如果没有任何city术语,保持运费不变(倍数设为1) $multiplier = $unique_city_count > 0 ? $unique_city_count : 1; // 调整运费 foreach ( $rates as $rate_key => $rate ) { $rates[$rate_key]->cost = $rate->cost * $multiplier; // 同步调整运费税(如果你的店铺需要计算运费税) if ( $rate->taxes ) { foreach ( $rate->taxes as $tax_key => $tax_cost ) { $rates[$rate_key]->taxes[$tax_key] = $tax_cost * $multiplier; } } } // 清除运费缓存,确保修改后的运费实时生效 WC()->session->set( 'shipping_for_package_0', false ); return $rates; }
关键修改点说明
- 用
array( 'fields' => 'slugs' )参数让wp_get_post_terms()直接返回术语的slug字符串,而非完整对象,让array_unique()能正确识别重复项。 - 添加了
is_wp_error()判断,避免商品未分配city分类时抛出错误。 - 用
count( array_unique(...) )直接统计唯一术语数量,省去了多余的循环计数器。 - 增加了运费税的同步调整(适配需要计算运费税的店铺场景)。
- 加入清除运费缓存的代码,确保修改后的运费能立即在前端显示。
排查建议
- 调试变量内容:在代码里加入
var_dump($unique_cities)或者error_log( print_r($unique_cities, true) ),查看存储的术语是否正确,去重后的数量是否符合预期。 - 测试边界情况:比如购物车只有一个商品、商品没有city术语、多个商品同属一个city术语的情况,验证运费计算是否正确。
- 检查分类法设置:确认你的自定义分类法
city确实正确分配给了商品,并且术语的slug没有重复。
内容的提问来源于stack exchange,提问作者Jure Zadravec
相关产品推荐
相关产品推荐

