Closure support in constant expressions in PHP 8.5
Marcos Marcolin • December 24, 2024 • 2 min read
php php85 phprfc opensourceClosures
In PHP, Closures are anonymous functions that can be assigned to variables, passed as arguments, or returned by other functions.
They're widely used to simplify the creation of callbacks and encapsulate specific logic that doesn't need to be defined as a named function. For example:
$greet = function ($name) {
return "Hello, $name!";
};
echo $greet("World"); // Output: Hello, World!
Or, since PHP 7.4 you could just write:
$greet = fn($name) => "Hello, $name!";
echo $greet("World"); // Output: Hello, World!
Closure support in constant expressions
It will now be possible to use Closures as part of constant expressions in PHP! This means you'll be able to define anonymous functions directly in:
- Attribute parameters
- Default values of properties and parameters
- Constants and class constants
Some important restrictions:
- Closures must be static (no access to
$this). - They cannot capture variables from the outer scope (
use).
Example:
function transformStrings(
array $strings,
array $transformations = [
static function ($value) {
return trim($value); // Removes extra whitespace
},
static function ($value) {
return ucfirst($value); // Capitalizes the first letter
},
]
) {
foreach ($strings as &$string) {
foreach ($transformations as $transformation) {
$string = $transformation($string);
}
}
return $strings;
}
var_dump(transformStrings([' hello', 'world ', ' php ']));
// array(3) { [0]=> string(5) "Hello" [1]=> string(5) "World" [2]=> string(3) "Php" }
What happens in the example above:
- The function receives a list of
stringsand applies transformations to each of them. - First, it removes extra whitespace around the
stringwithtrim. - Then, it capitalizes the first letter of each word with
ucfirst.
Now, an example using OOP:
class Dummy {
public function __construct(
public Closure $c,
) {}
}
// Defines a constant that stores a Dummy object with a Closure
const Closure = new Dummy(static function () {
echo "called", PHP_EOL;
});
// Runs the Closure stored in the object
(Closure->c)(); // Output: "called"
Simple explanation:
- The class receives a
Closureas a public property, stored on the instance. - It holds an instance of the
Dummyclass with theClosuredefined, which prints"called"when executed. - The expression
(Closure->c)()runs the Closure stored in the instance's publiccproperty.
This new feature also opens the door to other interesting use cases, such as using Closures in Attributes.
You can read more about the proposal in the official post: click here.
What do you think of this new feature? Share your thoughts in the comments!