PHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes.
The examples below begin with the core behavior, then move to an application-oriented use.
How PHP 8.5 Closures and First-Class Callables in Constant Expressions Works
PHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes.
Compatibility note: Requires PHP 8.5 or later.
Example 1: Basic Usage
This example uses a small input to make the main behavior visible.
<?php
final class Rule { public function __construct(public Closure $check = static fn(int $number): bool => $number > 0) {} }
$rule = new Rule();
var_dump(($rule->check)(5));
PHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes.
Example 2: A Different Input
A different set of values shows the same operation in another situation.
<?php
function normalizeCode(string $value): string { return strtoupper(trim($value)); }
final class CodeFormatter { public function __construct(public Closure $formatter = normalizeCode(...)) {} }
echo (new CodeFormatter())->formatter->__invoke(" a1 ");
The closure must satisfy constant-expression restrictions; capturing runtime variables is not available there.
Practical Example: Applying the Feature
This example shows an application-style use of the feature, with its surrounding setup visible.
<?php
#[Attribute]
class Validator { public function __construct(public Closure $check) {} }
#[Validator(static fn(string $value): bool => $value !== "")]
class Payload {}
$attribute = (new ReflectionClass(Payload::class))->getAttributes(Validator::class)[0]->newInstance();
var_dump(($attribute->check)("ready"));
The code is shown for learning. Adjust the class names, inputs and error handling to suit your application.
Important Behavior and Edge Cases
- The closure must satisfy constant-expression restrictions; capturing runtime variables is not available there.
- PHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes.
- Observe differences in empty inputs, invalid states and optional extension availability where relevant.
Comparison With Related Approaches
| Approach | Important Difference |
|---|---|
PHP 8.5 Closures and First-Class Callables in Constant Expressions | PHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes. |
| Alternative approach | Before PHP 8.5, callable objects often had to be created at runtime inside constructors. |
Common Beginner Mistakes
| Mistake | Correct Approach |
|---|---|
Ignoring the documented state or precondition of PHP 8.5 Closures and First-Class Callables in Constant Expressions | The closure must satisfy constant-expression restrictions; capturing runtime variables is not available there. |
| Expecting a different type of result | Read the declared return type and distinguish returned values from changes to the source object. |
| Assuming a related API works identically | Before PHP 8.5, callable objects often had to be created at runtime inside constructors. |
Key Takeaways
- PHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes.
- The closure must satisfy constant-expression restrictions; capturing runtime variables is not available there.
- Use the example that matches the values, runtime version and dependencies in your application.
PHP 8.5 Closures and First-Class Callables in Constant Expressions is useful when its behavior matches the data structure and lifecycle of your PHP application. Choose it with a clear understanding of its preconditions and returned values.