如何在PHP中从Recordset生成唯一日期数组并解决追加覆盖问题?
解决PHP遍历Recordset生成唯一日历日期列表的问题
我来帮你搞定这个从预订记录生成唯一日期数组的问题!先理清楚你的核心需求:从Recordset里的每条预订起止日期(date对应开始日,dateLast对应结束日),生成包含所有中间日期的去重后的日期数组,用来给日历做标记。
原始预订数据参考
每条记录的起止日期如下:
2019-01-19 - 2019-01-22
2019-01-19 - 2019-01-23
2019-01-20 - 2019-01-25
2019-01-22 - 2019-01-25
2019-01-27 - 2019-01-30
2019-01-29 - 2019-01-31
2019-02-01 - 2019-02-05
原代码的问题分析
你原来的代码只输出最后一条记录的日期,主要踩了这几个坑:
- 数组被反复清空:
$range = [];写在了while循环内部,每次循环都会重置数组,之前记录的日期全丢了,最后只剩最后一条的数据。 - 去重时机错误:在遍历单条记录的日期时就调用
array_unique,根本没把之前的所有日期积累起来,完全起不到全局去重的作用。 - 漏掉结束日期:
DatePeriod默认是不包含传入的结束日期的,所以每条记录的endDate都没被加入数组。
原代码片段(方便对照):
<?php $wa_startindex = 0; while(!$reservALL->atEnd()) { $wa_startindex = $reservALL->Index; ?> <?php $startDate = ($reservALL->getColumnVal("date")); $endDate = ($reservALL->getColumnVal("dateLast")); $format = "Y-m-d"; $begin = new DateTime($startDate); $end = new DateTime($endDate); $interval = new DateInterval('P1D'); // 1 Day $dateRange = new DatePeriod($begin, $interval, $end); $range = []; foreach ($dateRange as $date) { $range[] = $date->format($format); $result = array_unique($range, SORT_REGULAR); } ?> <?php $reservALL->moveNext(); } $reservALL->moveFirst(); //return RS to first record unset($wa_startindex); unset($wa_repeatcount); ?>
修正后的正确代码
下面是调整后的代码,解决了所有问题,还处理了空值的情况:
<?php $wa_startindex = 0; $range = []; // 把数组声明移到循环外,确保所有记录的日期都能积累进来 while(!$reservALL->atEnd()) { $wa_startindex = $reservALL->Index; // 读取当前记录的起止日期 $startDate = $reservALL->getColumnVal("date"); $endDate = $reservALL->getColumnVal("dateLast"); $format = "m-d-Y"; // 可根据需求改成Y-m-d $begin = new DateTime($startDate); $end = new DateTime($endDate); // 关键:给结束日期加1天,让DatePeriod包含原本的endDate $end->add(new DateInterval('P1D')); $interval = new DateInterval('P1D'); $dateRange = new DatePeriod($begin, $interval, $end); // 把当前记录的所有日期加入数组 foreach ($dateRange as $date) { $range[] = $date->format($format); } $reservALL->moveNext(); } // 全局去重,并用array_filter清理可能的空记录 $result = array_filter(array_unique($range)); // 重置Recordset指针 $reservALL->moveFirst(); // 清理临时变量 unset($wa_startindex); unset($wa_repeatcount); ?>
额外说明
- 空记录问题:之前出现的空值,是因为
DatePeriod在起止日期相同的极端情况下可能生成空项,array_filter可以自动清理这些无效值。 - 日期格式调整:如果需要还原成
Y-m-d格式,直接修改$format的值即可。 - 包含结束日期:通过
$end->add(new DateInterval('P1D')),让DatePeriod把原本的结束日期也包含进去,不会再漏掉预订的最后一天。
内容的提问来源于stack exchange,提问作者Burndog
相关产品推荐
相关产品推荐

