我正在尝试创建一个递归函数,以根据某些规则生成一组有效日期。
到目前为止,我已经有了这个功能
function progDateRange($date, $end_date, $wkDays, $excluded, $dates = array())
{
$valid_date = false;
$max_date = new DateTime(date('Y-m-d'));
$max_date->add(new DateInterval('P2Y'));
$max_date = $max_date->format('Y-m-d');
// is this date before the end date or the max date
if(strtotime($date) <= strtotime($end_date) && strtotime($date) <= strtotime($max_date))
{
if(!in_array($date, $excluded))
{
foreach($wkDays as $day => $val)
{
// is this date a valid weekday start
if(date("l", strtotime($date)) == $day) {
// successful date
$valid_date = true;
}
}
if($valid_date) {
array_push($dates, $date);
}
}
$next_day = new DateTime($date);
$next_day->add(new DateInterval('P1D'));
progDateRange($next_day->format('Y-m-d'), $end_date, $wkDays, $excluded, $dates);
} else {
return $dates;
}
}
我在一个单独的页面上使用它
$datesArray = progDateRange($date_start, $date_end, $wkDays, $excluded);
我传入了开始日期,结束日期,有效日期发生的工作日数组以及要排除的日期数组。
如果我print_r()
在函数中像这样
$next_day = new DateTime($date);
$next_day->add(new DateInterval('P1D'));
print_r($dates);
progDateRange($next_day->format('Y-m-d'), $end_date, $wkDays, $excluded, $dates);
每个循环都打印出数组并继续成功添加,但出于某种原因,当我在单独的页面上尝试和print_r($datesArray)
时,没有任何内容输出甚至没有空白数组,而我根本无法想象为什么。
我确信它会有些愚蠢,因为这个功能似乎在大多数情况下起作用,它只是在返回数据时磕磕绊绊。
我错过了什么?
我还尝试在return语句之前做一个print_r()
,这会返回我正试图抓住的确切数组。在调用函数的页面上返回/检索数据肯定会出现问题......
修改
正如我之前没有提到的,这里是$wkDays
和$excluded
$wkDays
生成
array(6) {
[0]=>
string(6) "Monday"
[1]=>
string(7) "Tuesday"
[2]=>
string(9) "Wednesday"
[3]=>
string(8) "Thursday"
[4]=>
string(6) "Friday"
[5]=>
string(6) "Sunday"
}
和$excludes
可能是这样的
array(23) {
[0]=>
string(10) "2013-04-22"
[1]=>
string(10) "2013-04-29"
[2]=>
string(10) "2013-05-13"
[3]=>
string(10) "2013-05-27"
[4]=>
string(10) "2013-06-03"
//...
}
示例调用可能会像这样;
progDateRange("2013-05-01", "2017-05-01", array("Monday", "Wednesday"), array("2013-06-12", "2013-06-19"));
解
以Jacks为例后,我不得不进行一些调整,结果就是这样;
function progDateRange($date, $end_date, $wkDays, $excluded)
{
$dates = array();
$todays_date = strtotime(date("Y-m-d"));
$current_date = strtotime($date);
$max_date = min(strtotime('+2 years'), strtotime($end_date));
while ($current_date < $max_date)
{
if (!in_array($date, $excluded) && in_array(date('l', $current_date), $wkDays) && $current_date > $todays_date) {
array_push($dates, $date);
}
$current_date = strtotime('+1 day', $current_date);
$date = date('Y-m-d', $current_date);
}
return $dates;
}
答案 0 :(得分:3)
在最后一次递归调用中没有返回$dates
的值,即函数结果为空;那说,你甚至不需要递归:
function progDateRange($date, $end_date, array $wkDays, array $excluded)
{
$dates = array();
$current_date = strtotime($date);
$max_date = min(strtotime('+2 years'), strtotime($end_date));
$dow = array_keys($wkDays);
while ($current_date < $max_date) {
if ($excluded && in_array($date_formatted, $excluded, true)) {
continue;
}
if (in_array(date('l'), $dow, true)) {
array_push($dates, $date);
}
$current_date = strtotime('+1 day', $current_date);
$date = date('Y-m-d', $current_date);
}
return $dates;
}
答案 1 :(得分:1)
您需要存储递归调用的结果。像这样:
$dates = array_merge(
$dates,
progDateRange($next_day->format('Y-m-d'), $end_date, $wkDays, $excluded, $dates)
);
或者,正如您可能已经尝试过的那样(看起来像),使用$ date作为引用参数的调用。请注意参数名称前的&
:
function progDateRange($date, $end_date, $wkDays, $excluded, &$dates = array())
但我更喜欢第一种方法