Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[HttpKernel] Handle multi-attribute controller arguments#40307
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
Uh oh!
There was an error while loading.Please reload this page.
Conversation
05ba4cb tobbef5bdComparesrc/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
nicolas-grekas commentedFeb 25, 2021
bbef5bd to9331628Comparejvasseur commentedFeb 25, 2021
I though of allowing multiple attributes when originally designing it but couldn't see the use-case. I see this feature as a potential replacement for the It's true that allowing multiple attributes doesn't limit the feature while allowing a potential new use case. The only things we will lose are:
Overall I would say I am slightly in disfavor of this PR since I see no use case for it while it has a few drawbacks but that's not a strong opinion. |
jvasseur commentedFeb 25, 2021
BTW, this PR is missing the update to theUserValueResolver to no longer use the deprecated API. |
9331628 tocf03bcbCompare07c36bb toe55c7a8Comparechalasr commentedFeb 25, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Thank you for reviewing.
I can imagine use cases other than value resolution (e.g. decoration, introspection, validation...). Making the assumption that only one attribute will be needed feels wrong to me.
Fixed |
f14e5c8 tode855a9Comparesrc/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
c13d68b to9c0b580Comparesrc/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
9c0b580 to921d638Comparesrc/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
871adb3 toc2c54e6Comparec2c54e6 tod771e44CompareUh oh!
There was an error while loading.Please reload this page.
| $representative =\get_class($representative); | ||
| foreach ($param->getAttributes()as$reflectionAttribute) { | ||
| if (class_exists($reflectionAttribute->getName())) { | ||
| $attributes[] =$reflectionAttribute->newInstance(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm still not convinced we should callnewInstance() on arbitrary attributes. Do we have a way to whitelist relevant attributes beforehand? Note that this is more or less what the now-deprecatedArgumentInterface did for us.
Alternatively: Can we make thenewInstance() call lazy, so we only perform it if$argumentMetadata->getAttributes(MyAttribute::class) is called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Sure, we could use some closures for that. But is it really worth it? Instantiation should not be heavy...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It shouldn't. Still, we triggerautoloading and attribute validation and execute someone else's code here. The reflection API intentionally gives us a way to prevent this. Why shouldn't we use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Well, the autoloading will get triggered anyway when usinggetAttributes inIS_INSTANCEOF mode since we have an argument resolver in Symfony that does that it will be triggered anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
You are right, autoloading might be triggered anyway if we useIS_INSTANCEOF.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The scope of the argument value resolver covers Symfony controllers exclusively.
Controllers are auto-registered callables that are executed at runtime, which might use third-party extensions we don't even know about. I mean, we do run someone else's code all the time in this area (take e.g sensio/framework-extra-bundle param converters... reflection-based logic is way more heavy there.)
So, after thinking twice at the possible alternatives, I propose to keep this PR as-is and iterate.
If someone comes up with a problematic case, we can reconsider pretty easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I propose to keep this PR as-is and iterate.
👍🏻 We agree on the goal of the PR and discuss an implementation detail here. Let's merge and I'll try to create a follow-up PR to avoid unwantednewInstance() calls.
If someone comes up with a problematic case, we can reconsider pretty easily.
Sorry for being so persistent here. I'd like to avoid the problematic case before the bugfix becomes a BC break.
derrabus commentedFeb 26, 2021
Thanks Robin for working on this feature, this is much appreciated. |
Currently, the
ArgumentMetadataclass used for controller argument value resolution can only hold one attribute per controller argument, while a method argument can take multiple attributes.This allows accessing all attributes for a given argument, and deprecates the
ArgumentInterfacebecause it is not needed.Spotted by@nicolas-grekas.