While 循环中嵌套foreach 循环可以使while 循环的条件通过吗?
Nested foreach loop in a While loop can make the condition for the while loop go over?
这里有一些关于我正在尝试创建的内容的背景知识。
我正在创建一个名为 getNextBilling($dateStart,$dateCount = 20)
的函数
你给它一个周期长度,这是你希望某人被计费的天数
$test->period = '2,5,15';
它需要一个开始日期
我已在测试页上分配
$test->getNextBilling('2015-06-12 00:00:00',2);
该功能应该做的是确保输入的日期是否早于当前日期以跳过本月的计费,这非常有效。
不起作用的是我的 while 循环中有一个 foreach
循环来查看输入的所有日期,我找不到使代码在实际显示的地方工作的方法你想要的天数。
上面的示例显示我想显示 2 天,输出是
Array
(
[1] => 2015-06-15
[2] => 2015-07-02
[3] => 2015-07-05
[4] => 2015-07-15
)
这是函数的代码
// SET START DATE
$startDate = new DateTime($dateStart);
// LOOP
$i = 1;
while($i <= $dateCount){
// LOOP THROUGH INPUTED DAYS
foreach($days as $day){
// CLEAN DAY
$day = formatNumbersOnly($day);
// SET LAST DAY
$lastDay = new DateTime($startDate->format('Y-m-d'));
$lastDay->modify('last day of this month');
// CHECK FOR PASSED DAY
if($day > $startDate->format('j')){
// CHECK FOR 28-29-30-31
if($day > $lastDay->format('j')){
// SET NEW DATE
$startDate->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$lastDay->format('j')
);
} else {
// SET NEW DATE
$startDate->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$day
);
}
// SET ARRAY
$nextBilling[$i] = $startDate->format('Y-m-d');
} else {
// SKIP
$i--;
}
// INCREASE COUNT
$i++;
}
// NEXT MONTH
$startDate->modify('1 month');
$startDate->setDate($startDate->format('Y'),$startDate->format('m'),1);
}
现在我明白问题出在哪里了,这是因为 foreach
循环内的计数增加了,但是当我把它放在外面时,它只会输出最后一天,如下所示:
Array
(
[-1] => 2015-06-15
[0] => 2015-07-15
[1] => 2015-08-15
[2] => 2015-09-15
)
如果有人有任何批评或提示,我们将不胜感激。我会继续努力修复它。
编辑: 我在 foreach
的开头添加了一个 if 语句来检查 $i
是否大于 $dateCount
它会跳出循环。感谢 Twisty 的时间和努力,我很感激。
很高兴您找到了答案。这是您找到它时我正在做的事情。
// SET START DATE
$startDate = new DateTime($dateStart);
$nextBill = new DateTime();
for($i=1;$i<$countDays;$i++){
switch(true){
case ($startDate->format('j') > $days[2]):
// go to next month
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m')+1,
$days[0];
);
break;
case ($startDate->format('j') > $days[1]):
// Is start date greater than 2nd billing (5)
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$days[2];
);
break;
case ($startDate->format('j') > $days[0]):
// is starteDate greater than 1st billing (2)
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$days[1];
);
break;
default:
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$days[0];
);
}
$nextBilling[$i] = $nextBill->format('Y-m-d');
$startDate = $nextBill->setDate(
$nextBill->format('Y'),
$nextBill->format('m'),
$nextBill->format('j')+1
);
}
这将确保如果 $startDate
是一个月的 1 号,它会显示 2 号,然后是 5 号。 id$startDate
是第3个,会显示第5个和第15个。如果$startDate
是20号,则显示下个月的2号和5号。
这里有一些关于我正在尝试创建的内容的背景知识。
我正在创建一个名为 getNextBilling($dateStart,$dateCount = 20)
你给它一个周期长度,这是你希望某人被计费的天数
$test->period = '2,5,15';
它需要一个开始日期 我已在测试页上分配
$test->getNextBilling('2015-06-12 00:00:00',2);
该功能应该做的是确保输入的日期是否早于当前日期以跳过本月的计费,这非常有效。
不起作用的是我的 while 循环中有一个 foreach
循环来查看输入的所有日期,我找不到使代码在实际显示的地方工作的方法你想要的天数。
上面的示例显示我想显示 2 天,输出是
Array
(
[1] => 2015-06-15
[2] => 2015-07-02
[3] => 2015-07-05
[4] => 2015-07-15
)
这是函数的代码
// SET START DATE
$startDate = new DateTime($dateStart);
// LOOP
$i = 1;
while($i <= $dateCount){
// LOOP THROUGH INPUTED DAYS
foreach($days as $day){
// CLEAN DAY
$day = formatNumbersOnly($day);
// SET LAST DAY
$lastDay = new DateTime($startDate->format('Y-m-d'));
$lastDay->modify('last day of this month');
// CHECK FOR PASSED DAY
if($day > $startDate->format('j')){
// CHECK FOR 28-29-30-31
if($day > $lastDay->format('j')){
// SET NEW DATE
$startDate->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$lastDay->format('j')
);
} else {
// SET NEW DATE
$startDate->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$day
);
}
// SET ARRAY
$nextBilling[$i] = $startDate->format('Y-m-d');
} else {
// SKIP
$i--;
}
// INCREASE COUNT
$i++;
}
// NEXT MONTH
$startDate->modify('1 month');
$startDate->setDate($startDate->format('Y'),$startDate->format('m'),1);
}
现在我明白问题出在哪里了,这是因为 foreach
循环内的计数增加了,但是当我把它放在外面时,它只会输出最后一天,如下所示:
Array
(
[-1] => 2015-06-15
[0] => 2015-07-15
[1] => 2015-08-15
[2] => 2015-09-15
)
如果有人有任何批评或提示,我们将不胜感激。我会继续努力修复它。
编辑: 我在 foreach
的开头添加了一个 if 语句来检查 $i
是否大于 $dateCount
它会跳出循环。感谢 Twisty 的时间和努力,我很感激。
很高兴您找到了答案。这是您找到它时我正在做的事情。
// SET START DATE
$startDate = new DateTime($dateStart);
$nextBill = new DateTime();
for($i=1;$i<$countDays;$i++){
switch(true){
case ($startDate->format('j') > $days[2]):
// go to next month
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m')+1,
$days[0];
);
break;
case ($startDate->format('j') > $days[1]):
// Is start date greater than 2nd billing (5)
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$days[2];
);
break;
case ($startDate->format('j') > $days[0]):
// is starteDate greater than 1st billing (2)
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$days[1];
);
break;
default:
$nextBill->setDate(
$startDate->format('Y'),
$startDate->format('m'),
$days[0];
);
}
$nextBilling[$i] = $nextBill->format('Y-m-d');
$startDate = $nextBill->setDate(
$nextBill->format('Y'),
$nextBill->format('m'),
$nextBill->format('j')+1
);
}
这将确保如果 $startDate
是一个月的 1 号,它会显示 2 号,然后是 5 号。 id$startDate
是第3个,会显示第5个和第15个。如果$startDate
是20号,则显示下个月的2号和5号。