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.