Anonymous Functions
Assigning an anonymous function to a variable
The most basic form looks just like a regular function definition, except there is no name between function and the parameter list. You capture the result in a variable, and that variable becomes callable.
A callable variable
<?php
$greet = function ($name) {
return "Hello, {$name}!";
};
echo $greet("Priya");
echo "\n";
echo gettype($greet);Hello, Priya! object
That last line is worth noticing: $greet is not a string containing code, it is an object of type Closure. That is what lets PHP call it with $greet(...), pass it to other functions, and even attach it to a class instance later on.
Anonymous functions as callback arguments
The main reason anonymous functions exist is to be passed directly as an argument, without ever being stored in a named variable first. array_map is a good starting example: it applies a callback to every element of an array and returns a new array of the results.
array_map with an inline anonymous function
<?php
$prices = [10, 25, 40];
$withTax = array_map(function ($price) {
return round($price * 1.13, 2);
}, $prices);
print_r($withTax);Array
(
[0] => 11.3
[1] => 28.25
[2] => 45.2
)array_filter follows the same pattern, but the callback returns a boolean: true keeps the element, false drops it.
array_filter with an inline anonymous function
<?php
$numbers = [3, 8, 12, 15, 21, 30];
$evens = array_filter($numbers, function ($n) {
return $n % 2 === 0;
});
print_r($evens);Array
(
[1] => 8
[2] => 12
[5] => 30
)Sorting with usort and a comparator
usort sorts an array in place using a comparator callback you supply. The callback receives two elements, $a and $b, and must return a negative number if $a should come first, a positive number if $b should come first, and zero if they are equal. Anonymous functions are the natural fit here because the comparison logic is usually specific to one call site.
Sorting an array of associative arrays by age
<?php
$people = [
['name' => 'Marco', 'age' => 34],
['name' => 'Aisha', 'age' => 22],
['name' => 'Devon', 'age' => 41],
];
usort($people, function ($a, $b) {
return $a['age'] <=> $b['age'];
});
foreach ($people as $person) {
echo "{$person['name']}: {$person['age']}\n";
}Aisha: 22 Marco: 34 Devon: 41
The spaceship operator <=> is doing the heavy lifting there — it compares two values and returns -1, 0, or 1, which is exactly the contract usort expects. Writing your own if/else comparison logic by hand works too, but <=> is shorter and less error-prone for simple numeric or string comparisons.
Immediately-invoked function expressions (IIFEs)
Sometimes you want to run a block of code once, immediately, without polluting the surrounding scope with temporary variables or a named function that never gets reused. Wrapping the anonymous function in parentheses and calling it right away — the IIFE pattern — solves that.
An IIFE that keeps a helper variable out of the outer scope
<?php
$config = (function () {
$defaults = ['timeout' => 30, 'retries' => 3];
$overrides = ['timeout' => 60];
return array_merge($defaults, $overrides);
})();
print_r($config);
// $defaults and $overrides never leak into this scopeArray
(
[timeout] => 60
[retries] => 3
)IIFEs are far less common in PHP than in JavaScript, since PHP files are usually included as whole scripts rather than concatenated together, but the pattern is still useful for one-off setup logic where you want strong scoping guarantees.
Anonymous functions cannot see outer variables by default
Forgetting to import an outer variable
<?php
$taxRate = 0.13;
$withTax = array_map(function ($price) {
return $price * (1 + $taxRate); // $taxRate is NOT visible here
}, [100, 200]);
print_r($withTax);Warning: Undefined variable $taxRate in ... on line 5
Array
(
[0] => 100
[1] => 200
)Fixing that requires the use ($taxRate) clause, which is covered in full on the Closures & use() page — that is the mechanism PHP gives you to deliberately pull outer variables into an anonymous function's own scope.
Anonymous functions are objects of type
Closure, which is whygettype()reportsobjectrather than something likefunction.array_maptransforms every element and returns a same-length array;array_filterremoves elements and keeps original keys.usortneeds a comparator that returns negative, zero, or positive — the spaceship operator<=>is the idiomatic way to produce that.An IIFE —
(function () { ... })()— runs once immediately and keeps its internal variables from leaking into the surrounding scope.