2015-06-22 1 views
1

Вот небольшой пример того, что я пытаюсь создать.Вложенный цикл foreach в цикле While может привести к тому, что условие для цикла while продолжается?

Я создаю функцию под названием getNextBilling($dateStart,$dateCount = 20)

Вы даете ему длину периода, который дни вы хотите кого-то, чтобы быть выставлен счет

$test->period = '2,5,15';

он принимает начальную дату, которая я назначенную на тестовой странице

$test->getNextBilling('2015-06-12 00:00:00',2);

Что должна делать функция, убедитесь, что введенные даты меньше текущей даты, чтобы пропустить этот месячный биллинг, который отлично работает.

Что не работает, так это то, что у меня есть цикл внутри моего цикла while, чтобы увидеть все введенные дни, я не могу найти способ заставить код работать там, где он на самом деле просто показывает количество дней, которое вы хотеть.

выше пример, который показывает, что я хочу, чтобы отобразить дней выход является

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 )

Если у кого есть какая-либо критика или советы, которые были бы весьма признательны. Я буду продолжать пытаться это исправить.

EDIT: Я добавил, если Постулаты в начале foreach, чтобы проверить, если $i больше $dateCount будет вырваться из петли. Спасибо Твисты за ваше время и усилия, я ценю это.

+0

Я не вижу, где ваш цикл foreach закрывается в вашем примере. – Twisty

+0

foreach закрывается после '// INCREASE COUNT $ i ++;' – Derek

+0

Где определяется '$ days'? – Twisty

ответ

0

Рад, что вы нашли ответ. Вот что я работаю, пока вы его нашли.

// 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 является первым месяцем, он показывает 2-й, а затем 5-й. Id $startDate является третьим, он покажет 5-й и 15-й. Если $startDate - 20-й, он отобразит 2-й и 5-й из следующего месяца.

+0

Это выглядит хорошо, однако вам нужно будет перейти на код, чтобы разрешить больше введенных дней? при объявлении периода, который пользователь может, если они хотят идти 'period (1,2,3,4,5,6,7,8,9,10)' – Derek

+0

Да, вы бы это сделали. Вы хотите создать цикл на основе 'count()' из $ days и декремента. – Twisty