Skip to content

[Mime] FormDataPart and multidimensional arrays structure #34031

Closed
@jvahldick

Description

@jvahldick

Symfony version(s) affected: 4.3

Description
I have had some issues trying to send (POST) data collections using the HttpClient component together with the Mime component.
The problem itself, or what I believe is a problem, lives on the Mime component.

Let's say I want to send a collection of names to the backend. Usually, what I've done can be seen on the code below:

<input type="text" name="names[]" value="John" />
<input type="text" name="names[]" value="Doe" />

It generates the following results on the $_POST globals on php

[
    'names' => [
        'John', 'Doe'
    ]
]

This is actual the raw body of the request:

----------------------------466490401959219490193856
Content-Disposition: form-data; name="names[]"

John
----------------------------466490401959219490193856
Content-Disposition: form-data; name="names[]"

Doe
----------------------------466490401959219490193856--

So, I tried to do same using the Symfony HttpClient:

$httpClient = new CurlHttpClient([
    'headers' => [
        'Content-Type' => 'multipart/form-data'
    ]
]);

$formFields = [
    'names' => [
        'John',
        'Doe',
    ],
];

$formData = new FormDataPart($formFields);

$response = $httpClient->request('POST', 'https://eng9788fdqqri.x.pipedream.net/', [
    'headers' => $formData->getPreparedHeaders()->toArray(),
    'body' => $formData->bodyToIterable(),
]);

The raw body received on the server was:

--_=_symfony_1571410806_b9d8ed1979329f4173335201a24a9293_=_
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data

John
--_=_symfony_1571410806_b9d8ed1979329f4173335201a24a9293_=_
Content-Type: text/plain; charset=utf-8; name=1
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=1

Doe
--_=_symfony_1571410806_b9d8ed1979329f4173335201a24a9293_=_--

Let's say I add more levels on the payload.

$formFields = [
    'people' => [
        [
            'forename' => 'John',
            'surname' => 'Doe',
            'visits' => [
                'Monday',
                'Tuesday',
            ]
        ],
        [
            'forename' => 'Foo',
            'surname' => 'Baz',
            'visits' => [
                'Monday',
                'Tuesday',
            ]
        ],
    ],
];

When building the form data, the fields are not well recognized as showing below

--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8; name=forename
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=forename

John
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8; name=surname
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=surname

Doe
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data

Monday
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8; name=1
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=1

Tuesday
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8; name=forename
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=forename

Foo
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8; name=surname
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=surname

Baz
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data

Monday
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_
Content-Type: text/plain; charset=utf-8; name=1
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name=1

Tuesday
--_=_symfony_1571411167_e78fb7990a9a6884b665462eb252cc74_=_--

As you can see, some names are repeated, and also, it is not actually well reconized by the server.
The result I got on this payload on Symfony ($request->request->all()) was:

{
    "request": {
        "forename": "John",
        "surname": "Doe"
    }
}

I created an example that can be checked at:
https://github.com/jvahldick/symfony-issue-mime-component/blob/master/src/Controller/MyController.php

There is a similar issue that can be found at #33063, which also has a PR (#33064).
I tested it, however, I didn't get what I believe is the desirable result.

What actually I expect to be the result is:

{
    "request": {
        "people": [
            {
                "forename": "John",
                "surname": "Doe",
                "visits": [
                    "Monday",
                    "Tuesday"
                ]
            },
            {
                "forename": "Foo",
                "surname": "Baz",
                "visits": [
                    "Monday",
                    "Tuesday"
                ]
            }
        ]
    }
}

Possible Solution
Will be creating the PR.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions