How PHP 8.5 Lets You Use Closures in Constant Expressions for Default Values
PHP 8.5 introduces support for closures inside constant expressions, allowing developers to define default parameter and property values directly with anonymous functions, and the article illustrates this new capability with clear code examples and explanations of its underlying rationale.
PHP 8.5 adds the ability to use closures in constant expressions, which makes it possible to define default values for function parameters or class properties directly with anonymous functions.
PHP structures that only accept “constant expressions” are limited to a small set of operations that produce immutable values. Property arguments are such a structure, and closures were not previously part of the allowed operations.
Since a closure is essentially PHP source code (or more precisely, PHP opcodes), it behaves as an immutable value, so there is no fundamental reason to forbid its use in constant expressions. Allowing closures opens up useful scenarios.
Below is a modern example showing a function that accepts a Closure as a default argument without needing a separate instantiation step:
function my_array_filter(
array $array,
Closure $callback = static function ($item) { return !empty($item); },
) {
$result = [];
foreach ($array as $item) {
if ($callback($item)) {
$result[] = $item;
}
}
return $result;
}
my_array_filter([0, 1, 2, '', 'foo', 'bar']); // returns [1, 2, "foo", "bar"]Before PHP 8.5, the same behaviour required a nullable default and an explicit assignment inside the function body:
function my_array_filter(array $array, ?Closure $callback = null) {
$callback ??= static fn($item) => !empty($item);
$result = [];
foreach ($array as $item) {
if ($callback($item)) {
$result[] = $item;
}
}
return $result;
}Beyond function parameters, the new feature enables closures in other constant contexts, such as class attributes and sub‑expressions. Example of a closure used in a PHP attribute for validation:
final class Locale {
#[Validator\Custom(static function (string $languageCode): bool {
return \preg_match('/^[a-z][a-z]$/', $languageCode);
})]
public string $languageCode;
}Another example shows an array of static closures passed as a default argument, each transforming an input string:
function foo(string $input, array $callbacks = [
static function ($value) { return \strtoupper($value); },
static function ($value) { return \preg_replace('/[^A-Z]/', '', $value); },
]) {
foreach ($callbacks as $callback) {
$input = $callback($input);
}
return $input;
}
foo('Hello, World!'); // string(10) "HELLOWORLD"These examples demonstrate how PHP 8.5’s support for closures in constant expressions simplifies default value definitions and expands the expressive power of the language.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
