WooCommerce购物车捆绑商品删除撤销、数量同步开发问题
捆绑商品删除后撤销同步恢复方案
手动往removed_cart_contents加数据不生效的核心原因有两个:
- 原有代码直接调用
WC()->cart->remove_cart_item()删除关联商品时,会重复触发woocommerce_cart_item_removed钩子造成递归执行,WooCommerce的会话保存逻辑会在钩子执行完成后重新覆写removed_cart_contents数据,手动追加的内容会被直接冲掉。 - 递归执行会打断WooCommerce原生的已删除商品持久化流程,关联商品的恢复数据不会被写入购物车会话,点击撤销时自然只能恢复最先删除的单个商品。
正确实现代码如下,增加递归防护,同时保证关联商品的恢复数据被正确写入:
add_action( 'woocommerce_cart_item_removed', 'cart_remove_bundle_items', 10, 2 ); function cart_remove_bundle_items($removed_cart_item_key, $cart) { static $is_removing = false; // 递归触发时直接跳出,避免死循环 if ($is_removing) return; $line_item = $cart->removed_cart_contents[ $removed_cart_item_key ]; if (empty($line_item['bundle_id'])) return; $bundle_id = $line_item['bundle_id']; $is_removing = true; foreach( $cart->get_cart() as $key => $item ){ if( $key !== $removed_cart_item_key && $item['bundle_id'] == $bundle_id ){ // 提前把关联商品写入已删除列表,保证恢复数据留存 $cart->removed_cart_contents[$key] = $item; // 执行删除操作,此时不会触发递归逻辑 $cart->remove_cart_item($key); } } $is_removing = false; }
代码生效后不需要额外编写恢复逻辑,WooCommerce原生撤销功能会自动识别removed_cart_contents内的同组关联商品,点击撤销时两个商品会同时恢复到购物车。
同bundle_id商品数量同步更新方案
使用woocommerce_update_cart_action_cart_updated钩子出现白屏、购物车清空的原因是:该钩子触发时WooCommerce尚未完成购物车数据合法性校验,在这个节点修改商品数量会打断原生校验流程,触发WooCommerce的异常商品清理逻辑,将所有商品判定为无效清空;如果没有做递归防护,还会出现死循环导致PHP内存溢出白屏。
正确实现需使用woocommerce_after_cart_item_quantity_update钩子,该钩子在单个商品数量更新完成、校验通过后触发,不会打断原生流程,搭配递归防护即可实现需求:
add_action( 'woocommerce_after_cart_item_quantity_update', 'sync_bundle_items_quantity', 10, 4 ); function sync_bundle_items_quantity($cart_item_key, $quantity, $old_quantity, $cart) { static $is_updating = false; if ($is_updating) return; $item = $cart->get_cart()[$cart_item_key] ?? null; if (empty($item['bundle_id'])) return; $bundle_id = $item['bundle_id']; // 强制数量最小为1,避免0值导致商品被删除 $target_quantity = max(1, intval($quantity)); $is_updating = true; foreach ($cart->get_cart() as $key => $cart_item) { if ($key !== $cart_item_key && $cart_item['bundle_id'] == $bundle_id) { // 第三个参数传false,不触发额外的更新钩子避免递归 $cart->set_quantity($key, $target_quantity, false); } } $is_updating = false; }
注意事项
- 添加捆绑商品到购物车时,要保证每一组捆绑商品的
bundle_id全局唯一,推荐用uniqid('bundle_')生成,不要用商品ID这类易重复的值,避免误关联不相关的商品。 - 上述代码建议放在子主题的
functions.php文件或者自定义功能插件中,不要直接写入父主题文件,避免主题更新时代码被覆盖。
内容的提问来源于stack exchange,提问作者Caluria
相关产品推荐
相关产品推荐

