发布于2026-07-20 阅读(0)
扫一扫,手机访问
本文介绍两种专业方法,实现仅统计购物车中特定商品 ID(如门票类商品)的数量,避免默认 get_cart_contents_count() 统计全部商品,从而精准控制结账页动态表单字段的生成逻辑。
在WooCommerce开发中,常会遇到一个需要根据购物车内容动态调整结账页面的场景。举个例子,你卖的是门票,一张门票对应一个参会人的姓名和证件号。那问题就来了:如果用户买了门票,同时又顺手买了件T恤,系统该怎么判断?直接用原生的 WC()->cart->get_cart_contents_count() 显然不行——它会把购物车里所有商品的数量全部累加,结果T恤也成了触发表单的“门票”,用户体验瞬间拉胯。
到底该怎么精准统计呢?下面给出两种方案,直接上干货。
这是最清晰、安全且容易维护的做法。核心思路是绕过全局计数函数,直接调用 WC_Cart::get_cart_item_quantities()。这个方法返回的是一个关联数组,键是商品ID,值是对应的数量——天然支持按ID筛选,不需要绕弯子。
add_action( 'woocommerce_before_order_notes', 'person_details' );
function person_details( $checkout ) {
if ( ! WC()->cart || WC()->cart->is_empty() ) {
return;
}
// 定义需统计的门票商品 ID 列表(请替换为你的真实商品 ID)
$ticket_product_ids = array( 30, 823, 53, 57 );
$total_ticket_count = 0;
foreach ( WC()->cart->get_cart_item_quantities() as $product_id => $quantity ) {
if ( in_array( (int) $product_id, $ticket_product_ids, true ) ) {
$total_ticket_count += $quantity;
}
}
// 动态生成 attendee 表单(从 1 开始编号)
for ( $i = 1; $i <= $total_ticket_count; $i++ ) {
echo '' . sprintf( __( 'Please enter details of attendee %d', 'textdomain' ), $i ) . '
';
woocommerce_form_field( "cstm_full_name{$i}", array(
'type' => 'text',
'class' => array( 'my-field-class form-row-wide' ),
'label' => __( 'Full name', 'textdomain' ),
'placeholder' => __( 'Enter full name', 'textdomain' ),
'required' => true,
), $checkout->get_value( "cstm_full_name{$i}" ) );
echo '';
}
}
✅ 优势说明:
- 不修改全局行为,不影响其他插件或主题对 get_cart_contents_count() 的调用;
- 支持多数量商品(如用户购买 2 张 ID=30 的票,自动计入 2 次);
- 使用 (int) 类型强转和 true 严格比较,避免字符串 ID 匹配异常;
- 增加 WC()->cart->is_empty() 防御性判断,提升健壮性。
如果项目里已经到处都在用 get_cart_contents_count(),改起来太麻烦,那么可以考虑用 woocommerce_cart_contents_count 过滤器来做一次“局部重写”。
add_filter( 'woocommerce_cart_contents_count', 'filter_ticket_cart_count', 10, 1 );
function filter_ticket_cart_count( $count ) {
if ( ! WC()->cart || WC()->cart->is_empty() ) {
return 0;
}
$ticket_product_ids = array( 30, 823, 53, 57 );
$filtered_count = 0;
foreach ( WC()->cart->get_cart_item_quantities() as $product_id => $quantity ) {
if ( in_array( (int) $product_id, $ticket_product_ids, true ) ) {
$filtered_count += $quantity;
}
}
return $filtered_count;
}
⚠️ 重要提醒:这种方式会全局覆盖 get_cart_contents_count() 的返回值——包括购物车小工具、页眉徽章、AJAX 更新等所有调用场景。除非你确实需要全站所有位置都只显示门票数量,否则不建议轻易尝试。
通过以上任一方案,你就能精准地驱动结账页动态表单,确保每个门票订单都获得恰好数量的实名信息采集入口,兼顾功能严谨性与用户体验。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8