
本文教你如何合并两个功能:为指定商品显示“去结算”按钮,同时对其他商品实现“已选择”状态提示,避免代码冲突并确保逻辑清晰可靠。
在 WooCommerce 主题或子主题的 functions.php 文件中,若分别启用「按商品 ID 自定义按钮文字」和「购物车中商品状态提示」两段代码,常因重复钩子调用、全局变量依赖(如 $woocommerce 已弃用)及逻辑嵌套不当导致功能失效甚至白屏。以下是经过重构、兼容性强且可维护的完整解决方案。
✅ 核心思路
将逻辑统一收口至单个 woocommerce_product_single_add_to_cart_text 过滤器中,并引入独立的 is_product_in_cart() 辅助函数,确保:
- 优先判断当前商品是否在购物车中;
- 再区分是否属于预设的「特殊商品」(如需跳转结算页);
- 所有分支覆盖完整,无遗漏返回值;
- 彻底弃用已废弃的 $woocommerce 全局对象,改用 WC()->cart。
? 完整可用代码
// 判断指定商品是否已在购物车中
function is_product_in_cart( $product_id ) {
if ( ! WC()->cart || ! WC()->cart->get_cart() ) {
return false;
}
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( $cart_item['product_id'] == $product_id ||
$cart_item['variation_id'] == $product_id ) {
return true;
}
}
return false;
}
// 统一控制“加入购物车”按钮文字
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' );
function woo_custom_cart_button_text() {
$current_product_id = get_the_ID();
$special_product_ids = array( 82, 74 ); // ✅ 替换为你需要设为"去结算"的商品ID
// 情况1:商品在购物车中,且属于特殊商品 → 显示"去结算"
if ( is_product_in_cart( $current_product_id ) && in_array( $current_product_id, $special_product_ids ) ) {
return __( 'Go to Checkout', 'woocommerce' );
}
// 情况2:商品在购物车中,但不属于特殊商品 → 显示"✓ 已选择"
if ( is_product_in_cart( $current_product_id ) && ! in_array( $current_product_id, $special_product_ids ) ) {
return __( '✓ already selected', 'woocommerce' );
}
// 情况3:商品不在购物车中 → 默认显示"Add to Cart"
return __( 'Add to Cart', 'woocommerce' );
}⚠️ 注意事项与最佳实践
- ID 类型兼容性:is_product_in_cart() 同时检查 product_id 和 variation_id,确保变体商品也能正确识别;
- 空购物车防护:函数开头添加 WC()->cart 存在性校验,防止未初始化时触发警告;
- 翻译就绪:所有文案均通过 __() 包裹,支持多语言主题;
- 性能优化:break 提前退出循环,避免遍历整个购物车;
- 调试建议:开发阶段可临时添加 error_log("Product {$current_product_id} in cart: " . var_export(is_product_in_cart($current_product_id), true)); 辅助排查。
✅ 效果验证清单
| 场景 | 预期按钮文字 |
|---|---|
| 访问 ID=82 的商品页(未加入购物车) | Go to Checkout |
| 访问 ID=82 的商品页(已在购物车) | Go to Checkout(保持不变,符合需求) |
| 访问普通商品页(未加入购物车) | Add to Cart |
| 访问普通商品页(已在购物车) | ✓ already selected |
将以上代码完整粘贴至子主题 functions.php 即可生效。无需插件,零依赖,一次配置,长期稳定。










