WooCommerce基于自定义字段数组实现数量阶梯定价代码调试需求
问题描述
每个产品都有一个名为prices的自定义字段,存储数量阶梯定价的JSON数组,示例如下:
{"USD":[{"unit_break":3000,"unit_price":"0.0850"},{"unit_break":6000,"unit_price":"0.0819"},{"unit_break":12000,"unit_price":"0.0795"},{"unit_break":18000,"unit_price":"0.0771"},{"unit_break":24000,"unit_price":"0.0742"},{"unit_break":30000,"unit_price":"0.0731"},{"unit_break":300000,"unit_price":"0.0719"}]}
需求逻辑:
当购物车商品数量小于等于某个
unit_break值时,对应使用该数组项的unit_price作为商品价格,逻辑示例:if cartquantity <= unit_break[0] { product price = unit_price[0] } else if cartquantity <= unit_break[1] { product price = unit_price[1] }
每个产品的阶梯数量不固定,需动态适配。现有代码仅能读取数组首个unit_break/unit_price项,无法处理后续阶梯,代码如下:
add_action( 'woocommerce_before_calculate_totals', 'quantity_based_bulk_pricing', 9999, 1 ); function quantity_based_bulk_pricing( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; // Loop through cart items foreach( $cart->get_cart() as $cart_item_key => $cart_item ) { // Get the bulk price from product custom field $prices = get_post_meta( $cart_item['product_id'], 'prices', true); $prices = json_decode($prices, true); $s = 0; foreach($prices as $price) { foreach($price as $unit) { $bulk_price = $unit['unit_break']; $qty_threshold = $unit['unit_price']; } $bulk_price = $price[$s]['unit_price']; $qty_threshold = $price[$s]['unit_break']; // Check if item quantity has reached the defined threshold if( $cart_item['quantity'] <= $qty_threshold) { // Set the bulk price $cart_item['data']->set_price( $bulk_price ); } //echo $qty_threshold.'<br>'; //echo $bulk_price; } } }
问题分析与修复
原代码核心问题:
- 嵌套循环逻辑混乱,外层遍历货币组后,未正确遍历所有阶梯定价,反而用固定索引
s=0仅取第一个阶梯 - 阈值判断逻辑缺失,没有按顺序匹配符合条件的阶梯后终止遍历
修正后的代码:
add_action( 'woocommerce_before_calculate_totals', 'quantity_based_bulk_pricing', 9999, 1 ); function quantity_based_bulk_pricing( $cart ) { // 后台非AJAX请求直接返回 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // 避免重复执行钩子 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; // 遍历购物车所有商品 foreach( $cart->get_cart() as $cart_item_key => $cart_item ) { $product_id = $cart_item['product_id']; $cart_qty = $cart_item['quantity']; // 获取并解析自定义定价字段 $prices_json = get_post_meta( $product_id, 'prices', true ); if ( empty($prices_json) ) continue; $prices = json_decode($prices_json, true); if ( empty($prices) || !is_array($prices) ) continue; $target_price = null; // 遍历货币组(默认取第一个有效货币组) foreach( $prices as $currency_prices ) { if ( !is_array($currency_prices) ) continue; // 按顺序遍历阶梯定价,匹配符合条件的价格 foreach( $currency_prices as $tier ) { $unit_break = (int)$tier['unit_break']; $unit_price = (float)$tier['unit_price']; // 购物车数量小于等于当前阶梯阈值时,记录价格并终止遍历 if ( $cart_qty <= $unit_break ) { $target_price = $unit_price; break 2; // 跳出两层循环,避免后续无效遍历 } } } // 成功匹配到阶梯价格时,设置商品单价 if ( $target_price !== null ) { $cart_item['data']->set_price( $target_price ); } } }
修复说明:
- 增加空值校验,避免JSON解析失败或字段为空引发报错
- 阶梯遍历逻辑优化:找到第一个符合条件的阶梯后立即终止循环,符合需求的顺序匹配逻辑
- 对
unit_break和unit_price做类型转换,避免字符串类型导致的比较错误 - 代码结构更清晰,逻辑分层明确,适配不同数量的阶梯定价
内容的提问来源于stack exchange,提问作者Trisha
相关产品推荐
相关产品推荐

