Skip to content

Commit 492097a

Browse files
committed
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
2 parents ed39fc8 + 30830fe commit 492097a

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

Command/Command.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,14 @@ public function setCode(callable $code)
281281
if ($code instanceof \Closure) {
282282
$r = new \ReflectionFunction($code);
283283
if (null === $r->getClosureThis()) {
284-
$code = \Closure::bind($code, $this);
284+
set_error_handler(static function () {});
285+
try {
286+
if ($c = \Closure::bind($code, $this)) {
287+
$code = $c;
288+
}
289+
} finally {
290+
restore_error_handler();
291+
}
285292
}
286293
}
287294

Tests/Command/CommandTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,18 @@ public function callableMethodCommand(InputInterface $input, OutputInterface $ou
398398
{
399399
$output->writeln('from the code...');
400400
}
401+
402+
public function testSetCodeWithStaticAnonymousFunction()
403+
{
404+
$command = new \TestCommand();
405+
$command->setCode(static function (InputInterface $input, OutputInterface $output) {
406+
$output->writeln(isset($this) ? 'bound' : 'not bound');
407+
});
408+
$tester = new CommandTester($command);
409+
$tester->execute([]);
410+
411+
$this->assertEquals('interact called'.\PHP_EOL.'not bound'.\PHP_EOL, $tester->getDisplay());
412+
}
401413
}
402414

403415
// In order to get an unbound closure, we should create it outside a class

0 commit comments

Comments
 (0)