[php-src] Issue #8421: Attributes that target functions are not valid for anonymous functions defined within a method
| From: | ollieread | Date: | Thu, 21 Apr 2022 17:12:06 +0000 |
| Subject: | [php-src] Issue #8421: Attributes that target functions are not valid for anonymous functions defined within a method | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-241135@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/8421
Author: ollieread
### Description
If an anonymous function is defined inside a method, attempting to create a new instance of any
attribute attached to it 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
<?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 works fine and gives no output, as expected. (https://3v4l.org/iDuIL#v8.1.4)
```php
<?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
<?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
<?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_