PHP 8.5 adds Closure::getCurrent(), which returns the Closure object for the closure that is currently executing. It is especially useful for recursive anonymous functions.
The Older Recursive Pattern
Before PHP 8.5, a recursive closure commonly had to capture a variable by reference.
Example:
<?php
$factorial = null;
$factorial = function (int $n) use (&$factorial): int {
return $n <= 1
? 1
: $n * $factorial($n - 1);
};
echo $factorial(5);
This works, but the closure depends on an external variable that must be initialized first.
Use Closure::getCurrent()
Example:
<?php
$factorial = function (int $n): int {
if ($n <= 1) {
return 1;
}
$self = Closure::getCurrent();
return $n * $self($n - 1);
};
echo $factorial(5);
Output:
120
What It Returns
Inside an executing closure, Closure::getCurrent() returns that current Closure instance. The value can be invoked like any other closure.
Call this method directly inside a closure. At top level or inside a named function, it throws an Error; it does not return the caller's closure.
Recursive Tree Walk
Example:
<?php
$walk = function (array $items, int $depth = 0): void {
$self = Closure::getCurrent();
foreach ($items as $item) {
echo str_repeat(' ', $depth) . $item['name'] . PHP_EOL;
if (!empty($item['children'])) {
$self($item['children'], $depth + 1);
}
}
};
This keeps the recursion self-contained instead of capturing the closure through a reference variable.
When to Use It
- Recursive anonymous functions
- Self-referential callbacks
- Algorithms where naming a separate function would add unnecessary scope
For large recursive algorithms, a named function or method can still be easier to document, test, and profile. Use Closure::getCurrent() when the behavior is naturally local.
Conclusion
Closure::getCurrent() removes a common workaround from recursive closures in PHP 8.5. It lets a closure access itself directly and keeps small recursive callbacks more self-contained.