Content · Web Development · PHP

PHP 8.5 Closures and First-Class Callables in Constant Expressions

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. See three examples and important limitations.

1 views Published Oct 17, 2026 Updated Oct 17, 2026 admin

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


ApproachImportant Difference
PHP 8.5 Closures and First-Class Callables in Constant ExpressionsPHP 8.5 permits static closures and first-class callables in constant-expression contexts such as defaults and attributes.
Alternative approachBefore PHP 8.5, callable objects often had to be created at runtime inside constructors.

Common Beginner Mistakes


MistakeCorrect Approach
Ignoring the documented state or precondition of PHP 8.5 Closures and First-Class Callables in Constant ExpressionsThe closure must satisfy constant-expression restrictions; capturing runtime variables is not available there.
Expecting a different type of resultRead the declared return type and distinguish returned values from changes to the source object.
Assuming a related API works identicallyBefore 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.

Share this resourceSend this page to someone who may find it useful.