An anonymous function, also called a closure, is a function with no name. You write function ($param) { ... } where a value is expected: assign it to a variable, pass it to another function, or return it. It can carry variables from the surrounding code with use ($var).
Every anonymous function is an object of the built-in class Closure, which is why it can be stored, passed around and called later with $greet(...).
The use keyword captures by value
A closure cannot see outside variables on its own. use ($x) copies the value of $x into the closure at the moment the closure is created, not when it runs:
use by reference: &$var
use (&$x) gives the closure the variable itself rather than a copy. Changes inside the closure are visible outside, and changes outside are seen inside. This is how a callback adds to a total or keeps a counter.
Each call to makeCounter() creates a new $count, and the returned closure keeps it alive after the function has returned. That is what "closure" refers to: the function closes over the variables it needs.
Pass a closure as a callback
Functions such as array_map(), array_filter(), usort() and array_walk() take a function as an argument. A closure lets you write it in place, with as many statements as the job needs:
When the body is a single expression, an arrow function like fn($p) => $p['price'] is shorter and needs no use.
Callables: function names, methods and strlen(...)
A parameter typed callable accepts more than closures. A string with a function name, an array with an object and a method name, and an array with a class name and a static method name all count. Since PHP 8.1, the first-class callable syntax strlen(...) turns any of them into a Closure directly.
The (...) form is checked when the line runs: a typo throws an Error right there. A string like 'strtoupr' is only a string until someone tries to call it.
Closures inside a class: $this and static
A closure created inside a method has $this bound automatically, so it can use the object's properties. Mark it static function when it does not need $this, which also stops it from keeping the object alive.
Forgetting use
The most common closure bug is using an outside variable without listing it in use. Inside the closure the variable does not exist:
$minAge = 18;
$adults = array_filter($people, function ($p) {
return $p['age'] >= $minAge; // $minAge is not in use (...)
});
PHP prints: Warning: Undefined variable $minAge
$minAge is null inside, any age compared >= null is true, and every person passes the filter. On a server that hides warnings, nothing tells you. Add the variable to use:
Frequently Asked Questions
What is a closure in PHP?
A function without a name, created with function (...) { ... } and stored in a variable or passed as an argument. PHP represents it as an object of the class Closure. It can carry variables from the scope where it was created, listed in use (...).
What does the use keyword do in a PHP closure?
use ($x) copies the outer variable $x into the closure when the closure is created. Later changes to $x outside are not seen. Write use (&$x) to share the variable instead, so changes go both ways.
What is a callable in PHP?
Anything PHP can call: a closure, a function name as a string ('strtoupper'), an array [$object, 'method'] or [ClassName::class, 'staticMethod'], or an object with __invoke(). Use the callable type to accept any of them and is_callable() to check.
What does strlen(...) mean in PHP?
It is the first-class callable syntax from PHP 8.1: strlen(...) creates a Closure from the function without calling it. It also works for methods, $obj->method(...), and static methods, Foo::bar(...), and is checked when the line runs, unlike a string name.
Do I need a semicolon after an anonymous function?
Yes, when you assign it: $f = function () { ... }; is an assignment statement, so it ends with ;. Leaving it out is a parse error. A closure passed directly as an argument needs no semicolon of its own.