-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
FormInterface is reported as \Traversable<string, FormInterface>
but can return int as key.
#46698
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
Comments
Note that if you don't turn on strict types in your file, the key implicitly casted as int by PHP will also be implicitly casted to string by the argument typehint. Deprecating numeric strings would break CollectionType for instance. |
Yes, I agree ; the issue only exists with strict_types. But I'm not sure the answer should be "We recommend to every Symfony user to not use strict_types".
This is with this formType I had the issue when trying to reproduce a similar ResizeFormListener. |
Any recommendation on this issue @nicolas-grekas or @xabbuh ? |
Option 5: Make sure integer keys are being cast back to string in our |
Seems like a nice idea @derrabus. We're using a OrderedHashMap for childrens symfony/src/Symfony/Component/Form/Form.php Line 155 in 870eeb9
The getIterator method is returning an OrderedHashMapIterator
And we could change the key method here:symfony/src/Symfony/Component/Form/Util/OrderedHashMapIterator.php Lines 110 to 119 in 123b165
Should I
Also, which branch should I target |
Dunno, like this? public function getIterator(): \Traversable
{
foreach ($this->children as $key => $value) {
yield (string) $key => $value;
}
}
Good question. Maybe we should play it safe and target 6.2. |
…incentLanglet) This PR was squashed before being merged into the 6.2 branch. Discussion ---------- [Form] Provide string keys when iterating on a form | Q | A | ------------- | --- | Branch? | 6.2 as recommended by #46698 (comment) | Bug fix? | no (?) | New feature? | no | Deprecations? | no | Tickets | Fix #46698 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> cc @derrabus Commits ------- 69de9a2 [Form] Provide string keys when iterating on a form
Symfony version(s) affected
5.0.0 and more
Description
Because the formBuilder use name as key, and because php is casting int-string like
'0'
to int, we sometimes ends with form name which is integer and this cannot be directly used by method likeFormInterface::remove
.How to reproduce
The following code
is not working when the form was build this way
Because the name is casted to an int when used as an array key here:
https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Form/FormBuilder.php#L71-L72
There are some situation in the Symfony code where the form names can be int and passed to method expecting string. One of them is the
ChoiceType
with expanded option.https://github.com/symfony/form/blob/6.1/Extension/Core/Type/ChoiceType.php#L407-L419
So far this code is working because
declare(strict_types=1);
is not used.But for my first example
if it's written in the userland with strict_types, it won't work even if all the phpdoc make believe it will:
\Traversable<string, FormInterface>
string
Possible Solution
I see at least four solutions here:
int|string
(since it's a BC-break, this might wait for 7.0)\Traversable<int|string, FormInterface>
with some comments; at least static-analysis user will be warned.$formBuilder->add('0')
it should be$formBuilder->add('prefix_0')
. And in SF 7.0, this will throw an exception.Additional Context
No response
The text was updated successfully, but these errors were encountered: