1

I have created a helper function to return the first valid payment date of the month. The day is not valid if it's a holiday (pulled from a list in a db table), a Saturday, or a Sunday. In this example the 1st January 2016 is a holiday.

I have created this recursive function in a CodeIgniter helper but I'm seeing really weird behaviour. What it should do is identify the 1st as a holiday, call itself to identify the 2nd as a Saturday, again to identify the 3rd as a Sunday, before eventually returning the 4th as the first valid day.

After the function calls itself, the part after the call will keep running in an infinite loop unless I insert a break;. If I do insert a break I get the following output:

2016-01-01: 1 
2016-01-02: 2 
2016-01-03: 3 
Final: 2016-01-04: 4 
Final: 2016-01-04: 4 
Final: 2016-01-03: 3 
Final: 2016-01-02: 2 

before finally returning 2 (which is wrong).

function day_check($paymentDate, $paymentDay = 1) {
    $CI =& get_instance();
    $dateParts = explode("-", $paymentDate);
    $holQ = $CI->db->query("SELECT * FROM holidays WHERE holidayDate = '$paymentDate'");
    $holR = $holQ->row();

    if ($paymentDay <= 0) {
        $paymentDay = 1;    
    }

    while (($holR->holidayDate == $paymentDate) || (date("l", strtotime($paymentDate)) == 'Saturday') || (date("l", strtotime($paymentDate)) == 'Sunday')) {
        echo "$paymentDate: $paymentDay <br>";
        $refinedDay = $dateParts[2] + 1;
        if ($refinedDay < 10) {
            $refinedDay = "0" . $refinedDay;    
        }
    $paymentDate = $dateParts[0] . "-" . $dateParts[1] . "-" . ($refinedDay);
    $paymentDay = $dateParts[2] + 1;
    day_check($paymentDate, $paymentDay);
    break;
    }


echo "Final: $paymentDate: $paymentDay <br>";
return $paymentDay;

}

Initial $paymentDate provided to function is 2016-01-01

I've been looking at this for hours and I don't understand why this is happening. Is this a quirk of Codeigniter or do I completely misunderstand my recursion logic?

  • 1
    `return day_check($paymentDate, $paymentDay);` resursive call shoud return, else you walk upward the stack again as your output shows – cske Jan 04 '16 at 12:46

1 Answers1

1

The problem is misunderstanding the logic. In your code the recursion call result is not used ever.

function day_check($paymentDate, $paymentDay = 1) {
    $CI =& get_instance();
    $dateParts = explode("-", $paymentDate);
    $holQ = $CI->db->query("SELECT * FROM holidays WHERE holidayDate = '$paymentDate'");
    $holR = $holQ->row();

    if ($paymentDay <= 0) {
        $paymentDay = 1;    
    }

    // while -> if
    if (($holR->holidayDate == $paymentDate) || (date("l", strtotime($paymentDate)) == 'Saturday') || (date("l", strtotime($paymentDate)) == 'Sunday')) {
        echo "$paymentDate: $paymentDay <br>";
        $refinedDay = $dateParts[2] + 1;
        if ($refinedDay < 10) {
            $refinedDay = "0" . $refinedDay;    
        }
    $paymentDate = $dateParts[0] . "-" . $dateParts[1] . "-" . ($refinedDay);
    $paymentDay = $dateParts[2] + 1;
    return day_check($paymentDate, $paymentDay); // return!
    // break; // no need
    }


echo "Final: $paymentDate: $paymentDay <br>";
return $paymentDay;

}

Also change while to if since we don't need a loop there.

Rango
  • 3,877
  • 2
  • 22
  • 32
  • Strictly speaking you even don't need a recursion for that. – Rango Jan 04 '16 at 12:52
  • Thank you, I feel sufficiently stupid for not realising that I required a return statement to call itself. –  Jan 04 '16 at 12:53