Closed
Description
Description
If an anonymous function is defined inside a method, attempting to create a new instance of any attribute attached to it, through reflection, that only targets functions (#[Attribute(Attribute::TARGET_FUNCTION)]
) will cause an error with the message.
Fatal error: Uncaught Error: Attribute "AttributeName" cannot target method (allowed targets: function)
This happens in both object and static contexts. Changing the attribute to work with methods instead will cause an inverted error if the closure is defined outside of a method within the global context.
Examples
This code works fine and gives no output, as expected. (https://3v4l.org/iDuIL#v8.1.4)
<?php
#[Attribute(Attribute::TARGET_FUNCTION)]
class FunctionAttribute
{
}
$closure = #[FunctionAttribute]
fn() => true;
class Something
{
public function get(Closure $closure)
{
return (new ReflectionFunction($closure))
->getAttributes(FunctionAttribute::class)[0]
->newInstance();
}
}
(new Something)->get($closure);
This code gives an error. (https://3v4l.org/Clenb#v8.1.4)
<?php
#[Attribute(Attribute::TARGET_FUNCTION)]
class FunctionAttribute
{
}
class Something
{
public function get()
{
$closure = #[FunctionAttribute]
fn() => true;
return (new ReflectionFunction($closure))
->getAttributes(FunctionAttribute::class)[0]
->newInstance();
}
}
(new Something)->get();
Its output is:
Fatal error: Uncaught Error: Attribute "FunctionAttribute" cannot target method (allowed targets: function) in /in/Clenb:16
Stack trace:
#0 /in/Clenb(16): ReflectionAttribute->newInstance()
#1 /in/Clenb(20): Something->get()
#2 {main}
thrown in /in/Clenb on line 16
Process exited with code 255.
As does this same code, but using a static method instead. (https://3v4l.org/s4Gk0#v8.1.4)
<?php
#[Attribute(Attribute::TARGET_FUNCTION)]
class FunctionAttribute
{
}
class Something
{
public static function get()
{
$closure = #[FunctionAttribute]
fn() => true;
return (new ReflectionFunction($closure))
->getAttributes(FunctionAttribute::class)[0]
->newInstance();
}
}
Something::get();
Which also outputs:
Fatal error: Uncaught Error: Attribute "FunctionAttribute" cannot target method (allowed targets: function) in /in/s4Gk0:16
Stack trace:
#0 /in/s4Gk0(16): ReflectionAttribute->newInstance()
#1 /in/s4Gk0(20): Something::get()
#2 {main}
thrown in /in/s4Gk0 on line 16
Process exited with code 255.
PHP Version
8.1.4
Operating System
No response