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

[DependencyInjection] Add support for named arguments#21383

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
fabpot merged 3 commits intosymfony:masterfromdunglas:di/named_arguments
Feb 13, 2017

Conversation

@dunglas
Copy link
Member

@dunglasdunglas commentedJan 23, 2017
edited by nicolas-grekas
Loading

QA
Branch?master
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?yes
Tests pass?yes
Fixed tickets-
LicenseMIT
Doc PRtodo

This PR introduces named arguments for services definitions. It's especially useful to inject parameters in an autowired service. It is (at least partially) an alternative to#21376 and#20738.

Usage:

services:_defaults:{ autowire: true }Acme\NewsletterManager:{ $apiKey: "%mandrill_api_key%" }# Alternative (traditional) syntaxservices:newsletter_manager:class:Acme\NewsletterManagerarguments:$apiKey:"%mandrill_api_key%"autowire:true
useDoctrine\ORM\EntityManager;usePsr\Log\LoggerInterface;namespaceAcme;class NewsletterManager{private$logger;private$em;private$apiKey;publicfunction__construct(LoggerInterface$logger,EntityManager$em,$apiKey)    {$this->logger =$logger;$this->em =$em;$this->apiKey =$apiKey;    }}

jvasseur, hason, chalasr, zanbaldwin, ro0NL, Exter-N, theofidry, yceruto, jean-pasqualini, apfelbox, and 11 more reacted with thumbs up emojiExter-N, theofidry, apfelbox, fesor, derrabus, sstok, and Zemistr reacted with hooray emoji
@nicolas-grekas
Copy link
Member

I like it.
Should be made to work with method calls.
Missing resources tracking for now.
With now two alts to#20738, I think we should close it :)

@fabpot
Copy link
Member

Note that this conflicts with the implementation of#21313 that was just merged.

@ogizanagi
Copy link
Contributor

ogizanagi commentedJan 23, 2017
edited
Loading

Note that this conflicts with the implementation of#21313 that was just merged.

Not really (AFAIU). But can't be used along with.

Side-note: I've already seen some projects using arguments keys, despite it had no effect until now (simply for "increasing readability"). Shouldn't it be considered as a BC break?

@fabpot
Copy link
Member

services:App\Foo\Bar:{'@baz', 'foo', apiKey: "%mandril_api_key%"}

@dunglas
Copy link
MemberAuthor

@ogizanagi in my opinion no, it was explicitly documented to support only packed arrays (see my changes inDefinition).
If it really matters, I can skip named parameters not matching instead of throwing, but it will be harder to debug.

@dunglas
Copy link
MemberAuthor

dunglas commentedJan 23, 2017
edited
Loading

Not really (AFAIU). But can't be used along with.

Indeed, I'll try to adapt my PR to be able to use both syntaxes together.

This would be nice but it actually doesn't work:

services:Acme\NewsletterManager:{ apiKey: "%mandril_api_key%" }

But this works:

services:Acme\NewsletterManager:arguments:{ apiKey: "%mandril_api_key%" }

@dunglas
Copy link
MemberAuthor

dunglas commentedJan 23, 2017
edited
Loading

@nicolas-grekas

Should be made to work with method calls.

It would be a nice addition, I propose to do it in another PR when this one will be reviewed and merged.

Missing resources tracking for now.

Done, I rely on@weaverryan's implementation for now because conditions to rebuild the container will be the same if we addcalls support later.

With now two alts to#20738, I think we should close it :)

Done!

@dunglas
Copy link
MemberAuthor

dunglas commentedJan 23, 2017
edited
Loading

@kasparsklavins we are trying to find the best way to inject parameters when using autowiring and service auto-registration (#21289). It will be a brand new way to use Symfony that will change drastically the first experience for new users and allow to develop faster.
For now, there is no way to do it. Please consider the big picture. Btw, you can already define a service using XML, YAML, PHP, your own loader, autowiring and so on...

@dunglas
Copy link
MemberAuthor

@fabpot@ogizanagi I've tried something to support the short syntax:b8c0e7c WDYT?

@ogizanagi
Copy link
Contributor

ogizanagi commentedJan 23, 2017
edited
Loading

Looks good to me, as soon as we warn in the documentation no argument should be named the same as one of the definition keywords, otherwise it won't work.
I don't know if we can do better for now :)

@ogizanagi
Copy link
Contributor

ogizanagi commentedJan 24, 2017
edited
Loading

Re-thinking about it, it also means introducing a new keyword someday means a potential BC break for someone using the short syntax along with named arguments 😕
So maybe this tradeoff isn't worth it and the short syntax should be kept for most simple usages.

@nicolas-grekas
Copy link
Member

Enforce a leading$, eg$apiKey: '%foo%'?
About method calls, is it that a big change ? Because that feels incomplete to me to not have it right now...

ogizanagi and chalasr reacted with thumbs up emoji

@linaori
Copy link
Contributor

One minor issue I see with this: when you rename a variable in php, it will now crash, but this won't be detected with applications (or bundles) with only unit-tests.

@dunglas
Copy link
MemberAuthor

@iltar you're right but it's already the case for traditional definitions (if you add or remove an argument it will fail) and forcalls definitions (if you rename the method it will fail).

It's why unit testing is not enough and apps need to have a pyramid of tests including some functional and UI ones.

@linaori
Copy link
Contributor

@dunglas correct, however, there's a bunch of refactoring tools and find/replaces that might modify the name of a variable. Correctly removing one without causing parse errors is a lot more complex, hence this issue is faster to present itself.

@dunglas
Copy link
MemberAuthor

dunglas commentedJan 24, 2017
edited
Loading

PR updated to make named arguments starting with a$ as suggested by@nicolas-grekas. It solves problems raided by@ogizanagi (no conflict possible now) and partially the one solved by@iltar (the $ makes it explicit that there is a special handling, and IDEs can add support for this new convention to allow fluent refactoring).

linaori and ogizanagi reacted with thumbs up emoji

}

if ($originalArguments !==$arguments) {
$value->setArguments($arguments);

Choose a reason for hiding this comment

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

ksort($arguments) before set?

*/
privatefunctionisUsingShortSyntax(array$service)
{
foreach ($serviceas$key =>$value) {

Choose a reason for hiding this comment

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

should be an|| instead of&&?
I'd write it asif (!isset($key[0]) || '$' !== $key[0]) {

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

should be an || instead of &&?

No it's correct (only int and keys starting with a $ are allowed when using short syntax)

}

if (is_array($service) &&array_values($service) ===$service) {
if (is_array($service) &&$this->isUsingShortSyntax($service)) {

Choose a reason for hiding this comment

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

note that array_values checked the order of keys, whereas isUsingShortSyntax doesn't anymore, isn't it?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Indeed, is it a problem?

Choose a reason for hiding this comment

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

no :)

*/
privatefunctionisUsingShortSyntax(array$service)
{
foreach ($serviceas$key =>$value) {
Copy link
Member

@nicolas-grekasnicolas-grekasJan 24, 2017
edited
Loading

Choose a reason for hiding this comment

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

the empty string case should also return false, isn't it? thus:
if (is_string($key) && ('' === $key || '$' !== $key[0])) {

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Why? If it's an empty, string, it's not a short definition.

Choose a reason for hiding this comment

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

that's exactly what I'm saying :)

dunglas reacted with laugh emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

done

@nicolas-grekasnicolas-grekas added this to the3.3 milestoneJan 24, 2017
@javiereguiluz
Copy link
Member

I don't like the$ at all. It makes the YAML file look a mix of PHP and YAML contents. Example:

arguments:$apiKey:"%mandrill_api_key%"
robfrawley, theofidry, Nicofuma, COil, hugohenrique, and teohhanhui reacted with thumbs up emojinicolas-grekas reacted with thumbs down emoji

@zanbaldwin
Copy link
Member

I think the$ is appropriate. It makes it much more obvious that the keys are directly referencing PHP variables/parameters (as defined in the method definition) rather than some non-trivial structure defined by something like the config component.
Making the arguments configuration seem a little less "magic" to newer developers (meaning a lower learning curve) is, to me personally, more important than clean looking configuration files.

nicolas-grekas, ogizanagi, chalasr, dunglas, and zmitic reacted with thumbs up emojirobfrawley, COil, and teohhanhui reacted with thumbs down emoji

@fabpot
Copy link
Member

@weaverryan Can we close#21376?

@fabpot
Copy link
Member

@dunglas Looks like another one where a doc PR is needed :)

@fabpot
Copy link
Member

Thank you@dunglas.

@fabpotfabpot merged commit8a126c8 intosymfony:masterFeb 13, 2017
fabpot added a commit that referenced this pull requestFeb 13, 2017
…(dunglas, nicolas-grekas)This PR was merged into the 3.3-dev branch.Discussion----------[DependencyInjection] Add support for named arguments| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | yes| Tests pass?   | yes| Fixed tickets | -| License       | MIT| Doc PR        | todoThis PR introduces named arguments for services definitions. It's especially useful to inject parameters in an autowired service. It is (at least partially) an alternative to#21376 and#20738.Usage:```ymlservices:    _defaults: { autowire: true }    Acme\NewsletterManager: { $apiKey: "%mandrill_api_key%" }# Alternative (traditional) syntaxservices:    newsletter_manager:        class: Acme\NewsletterManager        arguments:            $apiKey: "%mandrill_api_key%"        autowire: true``````phpuse Doctrine\ORM\EntityManager;use Psr\Log\LoggerInterface;namespace Acme;class NewsletterManager{    private $logger;    private $em;    private $apiKey;    public function __construct(LoggerInterface $logger, EntityManager $em, $apiKey)    {        $this->logger = $logger;        $this->em = $em;        $this->apiKey = $apiKey;    }}```Commits-------8a126c8 [DI] Deprecate string keys in arguments2ce36a6 [DependencyInjection] Add a new pass to check arguments validity6e50129 [DependencyInjection] Add support for named arguments
@weaverryan
Copy link
Member

I've at least got a docs issue opened for this!symfony/symfony-docs#7482

... and I closed my other PR -#21376

@teohhanhui
Copy link
Contributor

The$ prefix is unfortunate. PHP-ism seeping into YAML.

derrabus reacted with thumbs up emoji

@fabpotfabpot mentioned this pull requestMay 1, 2017
azine pushed a commit to azine/AzineMailgunWebhooksBundle that referenced this pull requestMay 6, 2017
This breaks on Symfony 3.3.0-Beta1 because of [changes in DI](symfony/symfony#21383 (comment)). Named keys have never been officially supported.
@dunglasdunglas deleted the di/named_arguments branchMay 9, 2017 10:03
*
* @throws InvalidArgumentException
*
* @return array
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be hinted as\ReflectionParameter[] so the following calls make more sense

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

This method has been removed during a subsequent refactoring.

*
* @throws InvalidArgumentException when $index isn't an integer
*/
publicfunctionreplaceArgument($index,$value)
Copy link
Contributor

Choose a reason for hiding this comment

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

the phpdoc of $index needs to be updated to allow string

Copy link
Contributor

Choose a reason for hiding this comment

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

also ChildDefinition::getArgument doesn't work with string yet. whereas you changed the parent Definition::getArgument.

fabpot added a commit that referenced this pull requestJun 5, 2017
…ition (dunglas)This PR was squashed before being merged into the 3.3 branch (closes#22981).Discussion----------[DependencyInjection] Fix named args support in ChildDefinition| Q             | A| ------------- | ---| Branch?       | 3.3| Bug fix?      | yes| New feature?  | no <!-- don't forget updating src/**/CHANGELOG.md files -->| BC breaks?    | no| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->| Tests pass?   | yes| Fixed tickets | n/a| License       | MIT| Doc PR        | n/aFollowing@Tobion's review of#21383.Commits-------1ab3e41 [DependencyInjection] Fix named args support in ChildDefinition
@alcohol
Copy link
Contributor

alcohol commentedJul 27, 2017
edited
Loading

For reasons unknown to me, my currently client had tons of service definitions that looked like:

service.id:class:Fooarguments:foo:somethingbar:somethingelse
<?phpclass Foo {publicfunction__construct($foo,$bar) {// $foo would be something// $bar would be somethingelse  }}

All of those broke with the introduction of these changes in 3.3.

Invalid key "X" found in arguments of method "X" for service "X": only integer or $named arguments are allowed.

Was this intentional? Was their use-case undocumented and thus not supported? Cause it did work exactly as expected before 3.3...

@linaori
Copy link
Contributor

Afaik, the keys were unused and therefore treated by sequence. Writing it down like this wasn't a supported feature either.

@alcohol
Copy link
Contributor

That's what I figured. They were using the keys themselves though in some cases, by retrieving the arguments of the service definition, in some CompilerPass related stuff. Took me a bit to sort everything out 😅

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@nicolas-grekasnicolas-grekasnicolas-grekas approved these changes

@chalasrchalasrchalasr left review comments

@weaverryanweaverryanweaverryan approved these changes

+2 more reviewers

@TobionTobionTobion left review comments

@GuilhemNGuilhemNGuilhemN left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

3.3

Development

Successfully merging this pull request may close these issues.

15 participants

@dunglas@nicolas-grekas@fabpot@ogizanagi@linaori@javiereguiluz@zanbaldwin@weaverryan@mvrhov@teohhanhui@alcohol@Tobion@GuilhemN@chalasr@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp