Skip to content

[Console] fixed BC issue with static closures #20847

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed

[Console] fixed BC issue with static closures #20847

wants to merge 3 commits into from

Conversation

araines
Copy link

@araines araines commented Dec 9, 2016

Q A
Branch? 2.8
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #20845
License MIT
Doc PR n/a

Static closures were unable to be used in Command::setCode since #14431. This change fixes the BC break and ensures static closures can still be used.

Edit: It seems the inability to bind static closures was considered a feature in PHP5 but was considered a bug by PHP7. As such, the tests need to work around this fact - but the code can remain the same. This code change can be tidied/removed once Symfony is PHP7+ only.

Discussion here:
https://bugs.php.net/bug.php?id=64761
https://bugs.php.net/bug.php?id=68792

Static closures were unable to be used in Command::setCode since #14431.
This change fixes the BC break and ensures static closures can still be
used.
@@ -283,7 +283,8 @@ public function setCode($code)
if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
$r = new \ReflectionFunction($code);
if (null === $r->getClosureThis()) {
$code = \Closure::bind($code, $this);
// Cannot bind static closures for PHP<7.0 so it may fail
$code = @\Closure::bind($code, $this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should find a way not requiring to silence errors. This is bypassing the issue

Copy link
Author

@araines araines Dec 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do completely agree, but I was really struggling to find a way around this - the only resources I could really find were from people who were doing it this way (or more convoluted ways which still required the errors being suppressed). If someone can come up with a better way, I'd much prefer it that way.

Assuming there isn't a better way, though - I could perhaps add a much more explanatory comment noting that it is only really needed for PHP5 compatibility and that the error suppress is unavoidable?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To explain a little further: The issue is that (as far as I can tell) there is no way to tell that a closure is static (or unbindable) without actually attempting to bind it and then seeing if it bound correctly. If it didn't bind, then you end up with what you started with.

So another solution would be to create a separate method isBindable(Closure $closure) which would return true or false. Ultimately within that method it would have to do an error-suppressed bind operation in order to determine whether it was possible. So that might result in slightly clearer code - but it would be fundamentally doing the same thing.

Here is a Stack Overflow question which highlights the problem and a potential solution quite well: http://stackoverflow.com/questions/28047640/determining-if-a-closure-is-static-in-php

$tester = new CommandTester($command);
$tester->execute(array());

if (version_compare(phpversion(), '7.0.0', '<')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use PHP_VERSION_ID for version comparisons

@nicolas-grekas nicolas-grekas added this to the 2.8 milestone Dec 9, 2016
@fabpot
Copy link
Member

fabpot commented Dec 13, 2016

👍

1 similar comment
@nicolas-grekas
Copy link
Member

👍

@fabpot
Copy link
Member

fabpot commented Dec 13, 2016

Thank you @araines.

fabpot added a commit that referenced this pull request Dec 13, 2016
This PR was squashed before being merged into the 2.8 branch (closes #20847).

Discussion
----------

[Console] fixed BC issue with static closures

| Q             | A
| ------------- | ---
| Branch?       | 2.8
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #20845
| License       | MIT
| Doc PR        | n/a

Static closures were unable to be used in Command::setCode since #14431.  This change fixes the BC break and ensures static closures can still be used.

Edit: It seems the inability to bind static closures was considered a feature in PHP5 but was considered a bug by PHP7.  As such, the tests need to work around this fact - but the code can remain the same.  This code change can be tidied/removed once Symfony is PHP7+ only.

Discussion here:
https://bugs.php.net/bug.php?id=64761
https://bugs.php.net/bug.php?id=68792

Commits
-------

3247308 [Console] fixed BC issue with static closures
@fabpot fabpot closed this Dec 13, 2016
@araines araines deleted the command-static-closures branch December 13, 2016 17:30
This was referenced Jan 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants