bug #39932 [Console] [Command] Fix Closure code binding when it is a static anonymous function (fancyweb)
This PR was merged into the 4.4 branch.
Discussion
----------
[Console] [Command] Fix Closure code binding when it is a static anonymous function
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
I'm building a single command application and I did:
```php
->setCode(static function (InputInterface $input, OutputInterface $output): void {
// my code
})
```
and it results in a warning `Cannot bind an instance to a static closure` + an exception `You must override the execute() method in the concrete command class.` I guess we should silently fail here if the Closure is not bindable.
Commits
-------
18d426871e
[Console][Command] Fix Closure code binding when it is a static anonymous function
This commit is contained in:
commit
c6f5e2a3b8
@ -281,7 +281,14 @@ class Command
|
|||||||
if ($code instanceof \Closure) {
|
if ($code instanceof \Closure) {
|
||||||
$r = new \ReflectionFunction($code);
|
$r = new \ReflectionFunction($code);
|
||||||
if (null === $r->getClosureThis()) {
|
if (null === $r->getClosureThis()) {
|
||||||
$code = \Closure::bind($code, $this);
|
set_error_handler(static function () {});
|
||||||
|
try {
|
||||||
|
if ($c = \Closure::bind($code, $this)) {
|
||||||
|
$code = $c;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,6 +398,18 @@ class CommandTest extends TestCase
|
|||||||
{
|
{
|
||||||
$output->writeln('from the code...');
|
$output->writeln('from the code...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSetCodeWithStaticAnonymousFunction()
|
||||||
|
{
|
||||||
|
$command = new \TestCommand();
|
||||||
|
$command->setCode(static function (InputInterface $input, OutputInterface $output) {
|
||||||
|
$output->writeln(isset($this) ? 'bound' : 'not bound');
|
||||||
|
});
|
||||||
|
$tester = new CommandTester($command);
|
||||||
|
$tester->execute([]);
|
||||||
|
|
||||||
|
$this->assertEquals('interact called'.\PHP_EOL.'not bound'.\PHP_EOL, $tester->getDisplay());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In order to get an unbound closure, we should create it outside a class
|
// In order to get an unbound closure, we should create it outside a class
|
||||||
|
Reference in New Issue
Block a user