WooCommerce优惠券插件开发出现woocommerce_cart_calculate_fees无限循环如何解决
WooCommerce赠品优惠券无限循环问题修复方案
问题根因
- 标识判断语法错误:你写的
if(!$this->adding)后面没有加花括号,仅global $woocommerce;这一行受判断限制,后续添加赠品的逻辑无论$this->adding的值是什么都会执行,导致判断标识完全失效。 - 钩子触发逻辑冲突:
WC_Cart::add_to_cart()方法执行时会触发购物车重算逻辑,必然会再次调用woocommerce_cart_calculate_fees钩子,就算标识判断写对了,也需要控制执行时机避免循环。 - 代码遗漏边界判断:缺少cookie不存在、优惠券数据解析失败的兼容判断,可能额外触发PHP报错。
修复方案
采用「双重防循环机制」解决问题:
- 入口处增加执行状态判断,如果已经在处理赠品添加逻辑直接返回
- 调用
add_to_cart前临时卸载当前钩子,添加完成后再重新挂载,从根源上避免重复触发
修正后完整代码示例
首先在你的插件类中声明状态属性:
// 类中增加属性声明,默认未执行添加逻辑 public $adding = false;
修正钩子回调方法:
public function c87_apply_coupon() { // 已经在执行赠品添加逻辑,直接返回避免循环 if ($this->adding) return; // 兼容cookie不存在的场景 if (!isset($_COOKIE['c87_coupon'])) return; $coupon = $_COOKIE['c87_coupon']; $coupon_values = json_decode(stripslashes($coupon)); // 兼容优惠券数据解析失败的场景 if (!$coupon_values || !isset($coupon_values->type)) return; switch($coupon_values->type) { case "GIFT": $this->c87_add_gift_to_cart(); break; case "ORDER_DISCOUNT": default: $this->c87_add_discount_to_order(75, $coupon_values); break; } }
修正赠品添加方法:
public function c87_add_gift_to_cart() { global $woocommerce; // 注意核对你要添加的赠品ID,原有代码判断的是61778、添加的是64148,这里统一为实际赠品ID $gift_product_id = 64148; $found = false; if(sizeof(WC()->cart->get_cart()) > 0) { foreach(WC()->cart->get_cart() as $cart_item_key => $values) { $_product = $values['data']; if($_product->get_id() == $gift_product_id) { $found = true; break; } } if(!$found) { // 添加前先标记为执行中,同时卸载当前钩子 $this->adding = true; remove_action('woocommerce_cart_calculate_fees', [$this, 'c87_apply_coupon']); $woocommerce->cart->add_to_cart($gift_product_id); // 执行完成后恢复状态、重新挂载钩子 add_action('woocommerce_cart_calculate_fees', [$this, 'c87_apply_coupon']); $this->adding = false; } } }
注意事项
- 确认赠品ID是否正确,原有代码中判断购物车是否存在的商品ID和实际添加的ID不一致,避免出现重复添加赠品的问题
- 如果赠品需要设置价格为0,可以在
add_to_cart之后通过购物车item的meta信息修改价格,或者配合woocommerce_before_calculate_totals钩子实现赠品免费逻辑
内容的提问来源于stack exchange,提问作者Udders
相关产品推荐
相关产品推荐

