Closures in PHP

PHP supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

<?php

// This function `intSeq` returns another function, which
// we define anonymously in the body of `intSeq`. The
// returned function closes over the variable `$i` to
// form a closure.
function intSeq() {
    $i = 0;
    return function() use (&$i) {
        $i++;
        return $i;
    };
}

// We call `intSeq`, assigning the result (a function)
// to `$nextInt`. This function value captures its
// own `$i` value, which will be updated each time
// we call `$nextInt`.
$nextInt = intSeq();

// See the effect of the closure by calling `$nextInt`
// a few times.
echo $nextInt() . "\n";
echo $nextInt() . "\n";
echo $nextInt() . "\n";

// To confirm that the state is unique to that
// particular function, create and test a new one.
$newInts = intSeq();
echo $newInts() . "\n";

To run the program, save it as closures.php and use the PHP CLI:

$ php closures.php
1
2
3
1

In PHP, closures are implemented using the Closure class. When defining an anonymous function, you can use the use keyword to inherit variables from the parent scope. The & before $i in use (&$i) allows the closure to modify the original variable, not just a copy.

The intSeq function returns an anonymous function that increments and returns $i. Each time we call this returned function, it remembers and modifies its own $i, demonstrating the closure’s state preservation.

By creating a new closure with $newInts = intSeq(), we show that each closure maintains its own independent state.

The last feature of functions we’ll look at for now is recursion.