Description
The following code:
declare(strict_types=1);
#[Attribute(Attribute::TARGET_PROPERTY)]
class TestAttribute
{
public function __construct(
public $callback
) {}
}
final class Clock
{
public function format(string $format): string
{
return $format;
}
}
final class Example
{
// This version FAILS (Fatal error: Constant expression contains invalid operations)
#[TestAttribute(static fn (Clock $clock) => $clock->format('Y-m-d H:i:s'))]
// This version PASSES
//#[TestAttribute(static function (Clock $clock) {
// return $clock->format('Y-m-d H:i:s');
//})]
public ?Clock $created_at = null;
}
$ref = new ReflectionProperty(Example::class, 'created_at');
$attr = $ref->getAttributes(TestAttribute::class)[0]->newInstance();
var_dump($attr->callback instanceof Closure);
Resulted in this output:
Fatal error: Constant expression contains invalid operations
But I expected this output instead:
bool(true)
https://3v4l.org/Hdf3V#v8.5.2
Both constructs produce a Closure and are runtime-equivalent. The difference appears to be a parser or constant-expression validation inconsistency. The RFC (https://wiki.php.net/rfc/closures_in_const_expr) uses normal anonymous functions as an example. Short closures aren't mention neither as known limitations / disallowed behavior nor future scope. If this is desired behavior and static short closures are not supported here - please this information somewhere to the docs
PHP Version
PHP 8.5.1 (cli) (built: Dec 18 2025 23:39:41) (NTS)
Copyright (c) The PHP Group
Built by Debian
Zend Engine v4.5.1, Copyright (c) Zend Technologies
with Zend OPcache v8.5.1, Copyright (c), by Zend Technologies
Operating System
No response
Description
The following code:
Resulted in this output:
Fatal error: Constant expression contains invalid operations
But I expected this output instead:
bool(true)
https://3v4l.org/Hdf3V#v8.5.2
Both constructs produce a Closure and are runtime-equivalent. The difference appears to be a parser or constant-expression validation inconsistency. The RFC (https://wiki.php.net/rfc/closures_in_const_expr) uses normal anonymous functions as an example. Short closures aren't mention neither as known limitations / disallowed behavior nor future scope. If this is desired behavior and static short closures are not supported here - please this information somewhere to the docs
PHP Version
Operating System
No response