Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Console] Bind the closure (code) to the Command if possible#14431

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
stof merged 1 commit intosymfony:2.8fromlyrixx:command-bind-this
Apr 23, 2015

Conversation

@lyrixx
Copy link
Member

QA
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets~
LicenseMIT
Doc PR~

This allow this kind of code:

#!/usr/bin/env php<?phprequire__DIR__.'/vendor/autoload.php';useSymfony\Component\Console\Application;useSymfony\Component\Console\Command\Command;useSymfony\Component\Console\Input\InputInterface;useSymfony\Component\Console\Output\OutputInterface;$application =newApplication();$application->add((newCommand('process')))    ->setDescription('Play all other commands')    ->setCode(function (InputInterface$input,OutputInterface$output)use ($application) {$application =$this->getApplication();$help =$application->find('help');$output->writeln($help->getHelp());    });$application->run();

@stof
Copy link
Member

how does this behave in case the closure passed as argument was already bound previously ?

@lyrixx
Copy link
MemberAuthor

Symfony is the last one to bind, so symfony wins:

#!/usr/bin/env php<?phprequire __DIR__.'/vendor/autoload.php';use Symfony\Component\Console\Application;use Symfony\Component\Console\Command\Command;use Symfony\Component\Console\Input\InputInterface;use Symfony\Component\Console\Output\OutputInterface;$application = new Application();$code = function (InputInterface $input, OutputInterface $output) use ($application) {    $output->writeln('===================');    $application = $this->getApplication();    $help = $application->find('help');    $output->writeln($help->getHelp());    $output->writeln('===================');};$code = $code->bindTo($application);$application->add((new Command('process')))    ->setDescription('Play all other commands')    ->setCode($code);$application->run();

=>

php test.php  process===================The %command.name% command displays help for a given command:  php %command.full_name% listYou can also output the help in other formats by using the --format option:  php %command.full_name% --format=xml listTo display the list of available commands, please use the list command.===================

(yeah, we can do crazy things with closure binding....)

Copy link
Contributor

Choose a reason for hiding this comment

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

Is the PHP version check necessary? In PHP 5.3 the instanceof check will return false, as theClosure class doesn't exist.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

You are right, but what if someone define a user-landClosure class ?

IHMO, it's safer to keep the version check (and will be removed in SF3.0 anyway)

edit: I did not know Closure exists since php 5.3

Choose a reason for hiding this comment

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

The Closure class exists since 5.3, but Closure::bind has been introduced in 5.4, so the check is required :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Aha! :)

@nicolas-grekas
Copy link
Member

I'd bind only if the closure is not already bound, so that we keep BC

@stof
Copy link
Member

The JS way to bind closures is better IMO, by making sure that the first one binding a closure wins, letting the creator of the closure can control how it is called without having to bother with code using the closure.

Is there a way to detect whether the closure was bound explicitly in PHP ?

@lyrixx
Copy link
MemberAuthor

Is there a way to detect whether the closure was bound explicitly in PHP ?

yes,http://php.net/manual/en/reflectionfunctionabstract.getclosurethis.php

if (PHP_VERSION_ID >=50400 &&$codeinstanceof \Closure) {$r =new \ReflectionFunction($code);if (null ===$r->getClosureThis()) {$code = \Closure::bind($code,$this);            }        }

but I'm not able to unbind a closure in tests ... (even if thedoc says it's possible)

@lyrixx
Copy link
MemberAuthor

Here we go, should be ok now...

Copy link
Member

Choose a reason for hiding this comment

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

typo:bound, notbinded

@lyrixxlyrixxforce-pushed thecommand-bind-this branch 3 times, most recently from6050e76 to71d7c25CompareApril 22, 2015 09:24
Copy link
Contributor

Choose a reason for hiding this comment

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

when it'snull should we throw an exception ?

Copy link
Member

Choose a reason for hiding this comment

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

Why ? This is precisely the case where we add a new feature

Copy link
Contributor

Choose a reason for hiding this comment

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

It's ok I understand now :D ,getClosureThis is not documented, so it would be nice if we add a comment that explain why we use it

@nicolas-grekas
Copy link
Member

👍

@lyrixx
Copy link
MemberAuthor

@stof Is it ok for you?

@stof
Copy link
Member

👍

@stof
Copy link
Member

Thanks@lyrixx.

@stofstof merged commitff4424a intosymfony:2.8Apr 23, 2015
stof added a commit that referenced this pull requestApr 23, 2015
…ssible (lyrixx)This PR was merged into the 2.8 branch.Discussion----------[Console] Bind the closure (code) to the Command if possible| Q             | A| ------------- | ---| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | no| Tests pass?   | yes| Fixed tickets | ~| License       | MIT| Doc PR        | ~This allow this kind of code:```php#!/usr/bin/env php<?phprequire __DIR__.'/vendor/autoload.php';use Symfony\Component\Console\Application;use Symfony\Component\Console\Command\Command;use Symfony\Component\Console\Input\InputInterface;use Symfony\Component\Console\Output\OutputInterface;$application = new Application();$application->add((new Command('process')))    ->setDescription('Play all other commands')    ->setCode(function (InputInterface $input, OutputInterface $output) use ($application) {        $application = $this->getApplication();        $help = $application->find('help');        $output->writeln($help->getHelp());    });$application->run();```Commits-------ff4424a [Console] Bind the closure (code) to the Command if possible
@fabpotfabpot mentioned this pull requestNov 16, 2015
@lyrixxlyrixx deleted the command-bind-this branchDecember 8, 2015 15:21
fabpot added a commit that referenced this pull requestDec 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/aStatic 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=64761https://bugs.php.net/bug.php?id=68792Commits-------3247308 [Console] fixed BC issue with static closures
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

6 participants

@lyrixx@stof@nicolas-grekas@jakzal@aitboudad@xabbuh

[8]ページ先頭

©2009-2025 Movatter.jp