WooCommerce自定义日期范围用户消费总额查询代码失效排查
以下是针对你的代码始终返回“该时间段无订单”的排查步骤和问题分析:
一、先确认查询是否真的没获取到订单
在$customer_orders = get_posts( $args );这一行后面添加调试代码,直接输出查询结果:
var_dump($customer_orders); die;
如果输出为空数组,说明get_posts的查询条件有问题;如果有订单数据,说明后续的过滤逻辑出错。
二、核心代码问题分析
1. 时间戳计算逻辑严重错误
$gap_days = $convert_ed_to_time; $gap_days_in_seconds = 60*60*24*$gap_days; $gap_time = $now - $gap_days_in_seconds;
strtotime($fetch_end_date)返回的是时间戳(从1970年到该日期的秒数),不是天数。你直接把这个秒数当成天数去乘86400(一天的秒数),会得到一个极其巨大的数值,导致$gap_time变成远小于所有订单日期的负数,所有订单都会被$customer_order_date > $gap_time过滤掉。
如果你的user_selected_date_period存储的是用户选择的开始日期(比如YYYY-MM-DD),正确逻辑应该是:
$gap_time = $convert_ed_to_time; // 循环里判断:if ( $customer_order_date >= $gap_time )
2. 用户元数据未做异常处理
如果用户还未设置自定义日期范围,get_user_meta会返回false,strtotime(false)会返回0(1970-01-01的时间戳),同样会导致过滤逻辑异常。需要先判断元数据是否存在:
$fetch_end_date = get_user_meta($user_id, $end_date, $single); if ( empty($fetch_end_date) || !strtotime($fetch_end_date) ) { // 处理未设置日期的情况,比如默认筛选近30天 $gap_time = strtotime('-30 days'); } else { $convert_ed_to_time = strtotime($fetch_end_date); $gap_time = $convert_ed_to_time; }
3. 双重日期过滤逻辑冲突
你先用date_query筛选了“本月+去年同月”的订单,之后又用$customer_order_date > $gap_time二次过滤,这两个逻辑可能完全重叠或矛盾。比如如果用户选择的日期范围不在这两个月内,date_query已经把订单过滤掉了,自然返回无订单。
如果要实现用户自定义日期范围,应该直接用date_query来筛选用户选择的开始和结束日期,而非固定的两个月:
// 假设用户存储了start_date和end_date两个元数据 $start_date = get_user_meta($user_id, 'user_selected_start_date', true); $end_date = get_user_meta($user_id, 'user_selected_end_date', true); $date_query = array(); if ( $start_date && strtotime($start_date) ) { $date_query['after'] = $start_date; } if ( $end_date && strtotime($end_date) ) { $date_query['before'] = $end_date; $date_query['inclusive'] = true; // 是否包含结束日期当天的订单 } $args = array( 'post_type' => 'shop_order', 'post_status' => array( 'wc-completed', 'wc-processing' ), 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => $user_id, 'date_query' => $date_query, );
4. 订单状态与用户关联验证
- 确认测试订单的状态确实是
completed或processing(在WooCommerce中,对应的post_status是wc-completed和wc-processing,可在wp_posts表中查看订单的post_status字段)。 - 确认测试订单的
_customer_user元值和当前用户ID一致(在wp_postmeta表中,查找对应订单ID的_customer_user记录)。
三、其他细节问题
return floatval( preg_replace( '#[^\d.]#', '', $total, $count ) );这里的$count是替换次数,不是订单数量,写法无意义,直接用floatval($total)即可,因为$order->get_total()返回的是数字字符串或浮点数。- 循环里的
$customer_order_date;是无效代码,可直接删除。
内容的提问来源于stack exchange,提问作者jarjar

