Skip to content
Fragmented Development

PHP recursion with anonymous functions

Edit: Quick update to implement syntax highlighting. Ooooh, ahhhh!

During development of Florrie, I ran into a situation that required recursion. However, I was working in a class, and didn't want to litter my class with single-purpose, non-reusable functions. I faced a problem; in PHP, is it possible for an anonymous function to call itself?

Background

First, I should clarify a little bit about the difference between static functions and anonymous functions in PHP. If you know all this stuff, skip down to the next section.

Static functions are the norm in PHP scripts. If you define a function like this, it's static:

function myFunction($arg) {
    echo $arg;
}
    
myFunction('Hiya'); // prints "Hiya"

The myFunction() function have been defined statically, and if you try to re-define them, you will receive the following fatal error: PHP Fatal error: Cannot redeclare myFunction.

A anonymous function, also called a closure, is declared inline and used by another section of code. They are defined this way:

$myFunction = function($arg) {
    echo $arg;
}

$myFunction('Heyo');    // Prints "Heyo"

These types of functions are used often as callback functions, so you don't have an extra static function lying around that only does one thing. Anonymous functions don't have to be assigned to a variable; they can be inserted directly as a function argument as well. Here's a quick example using array_map:

$values = array('foo', 'bar', 'baz');

array_map(function($value){ echo $value, ' '; }, $values);
// Will print "foo bar baz "

So, back to the original question: can you use an anonymous function recursively?

It turns out that yes, it is possible for an anonymous function to call itself. There are a few methods of doing it, but only one makes very much sense.

The use keyword

To use an anonymous function recursively, we need to give it a way to call itself. Unfortunately, there is no built-in way to do this; it would be really nice if PHP gave us a magic variable that could be used to reference the current function, or if they defined $this to be a reference to the current closure. That doesn't seem to be the case, though. Maybe in a future version?

Currently, the only way to allow an anonymous function to call itself is to assign it to a variable, and give the anonymous function a reference to itself using the use keyword.

Since this has to be done while the anonymous function is being defined, it has to be sent in by reference; sending a copy of a function before its defined gets you into a nasty catch-22 scenario.

For a quick example, here is the recursive factorial example done in PHP:

$factorial = function($value) use (&$factorial) {

    if($value <= 1) {
        return 1;
    }

    return $value * $factorial($value - 1);
};

echo $factorial(4);    // Prints "24"

I'm using this for recursively parsing & processing XML files, but you could use it for any place that you need a little recursion without adding extra functions.

Reference: Anonymous recursive PHP functions

Tags: php


Add Your Comment