Before PHP 8.5, implementing recursion in a closure required binding the closure to a reference variable at creation time so it could call itself. This approach worked, but it was confusing and easy to overlook. It also introduced an extra layer of indirection - recursion depended on an external variable rather than the closure being self-contained.
In the following example, the $fibonacci variable is first declared as a closure and then immediately passed into the closure by reference. This allows the closure to call $fibonacci() from within its own body, enabling recursion.
<?php
$fibonacci = function (int $n) use (&$fibonacci) {
if (0 === $n || 1 === $n) {
return $n;
}
return $fibonacci($n - 1) + $fibonacci($n - 2);
};
echo $fibonacci(20); // 6765
Since PHP 8.5, we can use the Closure::getCurrent static method to get the currently executing closure. It allows simplifying recursion implementation in the closure.
In the following example, the $fibonacci closure no longer needs a use clause to reference itself. Instead, it calls the Closure::getCurrent method to retrieve the closure that is currently running.
<?php
$fibonacci = function (int $n) {
if (0 === $n || 1 === $n) {
return $n;
}
$fibonacci = Closure::getCurrent();
return $fibonacci($n - 1) + $fibonacci($n - 2);
};
echo $fibonacci(20); // 6765
Leave a Comment
Cancel reply