Recursive functions can be very useful when developing in PHP.

A recursive function is simply a function that calls itself, but why would you want your function to be able to call itself?

They are best used when a problem needs to be solved by breaking it up into a smaller instance of itself. Examples of this would be calculation a factorial or the Fibonacci Series.

Let’s take a look at the Fibonacci Series as an example. The series looks like this…

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

It can be described using the following formula,

F_{n} = F_{n-1} + F_{n-2}

with the seed values,

F_{0} = 0, F_{1} = 1

As you can see in the formula’s definition, it has to call itself for n-1 and n-2 to work out the current value for n.

So how would we write this in PHP?

A simple function like this should do the trick.

1 2 3 4 5 6 7 8 9 10 11 |
function fib($n) { if ($n < 0) { return NULL; } elseif ($n === 0) { return 0; } elseif ($n === 1 || $n === 2) { return 1; } else { return fib($n-1) + fib($n-2); } } |

As you can see I have added some guard statements, so if $n is 0, we return NULL (as the Fibonacci series starts at 0 and works up from there), for 0 we know the seed value is 0 and for 1 and 2 we know the seed values are 1. As we now know the start of the series, we can call our function to work out any part of the series.

For very large values of $n, there will be a lot of recursion, and this could use a lot of computer resources. Each call to fib (apart from to values 0, 1 & 2) costs us at least two more calls to fib, and these calls could be making more calls as it recurses. For example, when $n is 19, there would be 8361 calls made to the fib function to calculate the result, and when $n is 29, there would be 1028457 calls. It’s easy to see that although this is a very simple formula, it can end up being very expensive to use.

However, we can optimise the code and make things easier. We are constantly calculating the same values multiple times, so this should be telling you that this is an ideal candidate for caching.

Let’s modify our function to keep already calculated values of $n in an array and return those if possible rather than recalculating each call.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function fib($n) { static $cache; if ($n < 0) { return NULL; } elseif ($n === 0) { return 0; } elseif ($n === 1 || $n === 2) { return 1; } else { if (!(!is_null($cache) && array_key_exists($n, $cache))) { $cache[$n] = fib($n-1) + fib($n-2); } return $cache[$n]; } } |

Here we are using a static variable to persist the $cache between calls. Then before recursively calling the fib function we check if the $cache isn’t null and if the $cache has data stored with the key value of $n. If it doesn’t we calculate the can cache the data. Finally we return the value from the cache.

Now when we call the function for when $n = 19, our function is only called 35 times, and for $n = 29, our function is only called 55 times. That’s saved us 1028402 calls!

I hope this has been a useful quick look at recursive functions using PHP.